From c5c49f47859b8faf4817d84b5ae1415ea08b4e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Smyrek?= Date: Thu, 12 Nov 2020 12:20:31 +0100 Subject: [PATCH 1/5] Added `toArray()` helper to cast any value to an array --- .../src/conversion/conversion.js | 9 +++-- .../src/conversion/downcasthelpers.js | 5 +-- packages/ckeditor5-engine/src/view/element.js | 10 +++--- .../tests/conversion/upcasthelpers.js | 4 ++- .../src/image/imageinsertcommand.js | 5 ++- .../src/imageupload/imageuploadcommand.js | 5 ++- .../src/mediaregistry.js | 7 ++-- packages/ckeditor5-table/package.json | 2 +- .../src/converters/downcast.js | 13 +++----- .../tests/twostepcaretmovement.js | 6 ++-- packages/ckeditor5-ui/src/template.js | 11 +++---- packages/ckeditor5-undo/tests/redocommand.js | 3 +- packages/ckeditor5-undo/tests/undocommand.js | 3 +- packages/ckeditor5-utils/src/locale.js | 5 ++- packages/ckeditor5-utils/src/toarray.js | 18 ++++++++++ packages/ckeditor5-utils/tests/toarray.js | 33 +++++++++++++++++++ packages/ckeditor5-watchdog/package.json | 4 +-- .../ckeditor5-watchdog/src/contextwatchdog.js | 9 ++--- packages/ckeditor5-widget/src/utils.js | 10 ++---- packages/ckeditor5-widget/tests/widget.js | 6 ++-- 20 files changed, 100 insertions(+), 68 deletions(-) create mode 100644 packages/ckeditor5-utils/src/toarray.js create mode 100644 packages/ckeditor5-utils/tests/toarray.js diff --git a/packages/ckeditor5-engine/src/conversion/conversion.js b/packages/ckeditor5-engine/src/conversion/conversion.js index 9751a806698..536911d6ed6 100644 --- a/packages/ckeditor5-engine/src/conversion/conversion.js +++ b/packages/ckeditor5-engine/src/conversion/conversion.js @@ -10,6 +10,7 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import UpcastHelpers from './upcasthelpers'; import DowncastHelpers from './downcasthelpers'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * A utility class that helps add converters to upcast and downcast dispatchers. @@ -74,10 +75,10 @@ export default class Conversion { this._helpers = new Map(); // Define default 'downcast' & 'upcast' dispatchers groups. Those groups are always available as two-way converters needs them. - this._downcast = Array.isArray( downcastDispatchers ) ? downcastDispatchers : [ downcastDispatchers ]; + this._downcast = toArray( downcastDispatchers ); this._createConversionHelpers( { name: 'downcast', dispatchers: this._downcast, isDowncast: true } ); - this._upcast = Array.isArray( upcastDispatchers ) ? upcastDispatchers : [ upcastDispatchers ]; + this._upcast = toArray( upcastDispatchers ); this._createConversionHelpers( { name: 'upcast', dispatchers: this._upcast, isDowncast: false } ); } @@ -636,9 +637,7 @@ function* _getUpcastDefinition( model, view, upcastAlso ) { yield { model, view }; if ( upcastAlso ) { - upcastAlso = Array.isArray( upcastAlso ) ? upcastAlso : [ upcastAlso ]; - - for ( const upcastAlsoItem of upcastAlso ) { + for ( const upcastAlsoItem of toArray( upcastAlso ) ) { yield { model, view: upcastAlsoItem }; } } diff --git a/packages/ckeditor5-engine/src/conversion/downcasthelpers.js b/packages/ckeditor5-engine/src/conversion/downcasthelpers.js index a3116f5aee9..6cf9338e9b3 100644 --- a/packages/ckeditor5-engine/src/conversion/downcasthelpers.js +++ b/packages/ckeditor5-engine/src/conversion/downcasthelpers.js @@ -19,6 +19,7 @@ import ConversionHelpers from './conversionhelpers'; import { cloneDeep } from 'lodash-es'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * Downcast conversion helper functions. @@ -1136,7 +1137,7 @@ function changeAttribute( attributeCreator ) { // First remove the old attribute if there was one. if ( data.attributeOldValue !== null && oldAttribute ) { if ( oldAttribute.key == 'class' ) { - const classes = Array.isArray( oldAttribute.value ) ? oldAttribute.value : [ oldAttribute.value ]; + const classes = toArray( oldAttribute.value ); for ( const className of classes ) { viewWriter.removeClass( className, viewElement ); @@ -1155,7 +1156,7 @@ function changeAttribute( attributeCreator ) { // Then set the new attribute. if ( data.attributeNewValue !== null && newAttribute ) { if ( newAttribute.key == 'class' ) { - const classes = Array.isArray( newAttribute.value ) ? newAttribute.value : [ newAttribute.value ]; + const classes = toArray( newAttribute.value ); for ( const className of classes ) { viewWriter.addClass( className, viewElement ); diff --git a/packages/ckeditor5-engine/src/view/element.js b/packages/ckeditor5-engine/src/view/element.js index bc9d124f474..52681e38af9 100644 --- a/packages/ckeditor5-engine/src/view/element.js +++ b/packages/ckeditor5-engine/src/view/element.js @@ -11,6 +11,7 @@ import Node from './node'; import Text from './text'; import TextProxy from './textproxy'; import toMap from '@ckeditor/ckeditor5-utils/src/tomap'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable'; import Matcher from './matcher'; import StylesMap from './stylesmap'; @@ -724,8 +725,7 @@ export default class Element extends Node { _addClass( className ) { this._fireChange( 'attributes', this ); - className = Array.isArray( className ) ? className : [ className ]; - className.forEach( name => this._classes.add( name ) ); + toArray( className ).forEach( name => this._classes.add( name ) ); } /** @@ -742,8 +742,7 @@ export default class Element extends Node { _removeClass( className ) { this._fireChange( 'attributes', this ); - className = Array.isArray( className ) ? className : [ className ]; - className.forEach( name => this._classes.delete( name ) ); + toArray( className ).forEach( name => this._classes.delete( name ) ); } /** @@ -789,8 +788,7 @@ export default class Element extends Node { _removeStyle( property ) { this._fireChange( 'attributes', this ); - property = Array.isArray( property ) ? property : [ property ]; - property.forEach( name => this._styles.remove( name ) ); + toArray( property ).forEach( name => this._styles.remove( name ) ); } /** diff --git a/packages/ckeditor5-engine/tests/conversion/upcasthelpers.js b/packages/ckeditor5-engine/tests/conversion/upcasthelpers.js index ce1dd9de860..38c0771165c 100644 --- a/packages/ckeditor5-engine/tests/conversion/upcasthelpers.js +++ b/packages/ckeditor5-engine/tests/conversion/upcasthelpers.js @@ -31,6 +31,8 @@ import ViewRange from '../../src/view/range'; import { StylesProcessor } from '../../src/view/stylesmap'; import Writer from '../../src/model/writer'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; + /* globals console */ describe( 'UpcastHelpers', () => { @@ -899,7 +901,7 @@ describe( 'UpcastHelpers', () => { const conversionResult = model.change( writer => upcastDispatcher.convert( viewToConvert, writer ) ); if ( markers ) { - markers = Array.isArray( markers ) ? markers : [ markers ]; + markers = toArray( markers ); for ( const marker of markers ) { expect( conversionResult.markers.has( marker.name ) ).to.be.true; diff --git a/packages/ckeditor5-image/src/image/imageinsertcommand.js b/packages/ckeditor5-image/src/image/imageinsertcommand.js index d30ca525dc1..eb8149de5ee 100644 --- a/packages/ckeditor5-image/src/image/imageinsertcommand.js +++ b/packages/ckeditor5-image/src/image/imageinsertcommand.js @@ -5,6 +5,7 @@ import Command from '@ckeditor/ckeditor5-core/src/command'; import { insertImage, isImageAllowed } from './utils'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * @module image/image/imageinsertcommand @@ -50,9 +51,7 @@ export default class ImageInsertCommand extends Command { execute( options ) { const model = this.editor.model; - const sources = Array.isArray( options.source ) ? options.source : [ options.source ]; - - for ( const src of sources ) { + for ( const src of toArray( options.source ) ) { insertImage( model, { src } ); } } diff --git a/packages/ckeditor5-image/src/imageupload/imageuploadcommand.js b/packages/ckeditor5-image/src/imageupload/imageuploadcommand.js index d6182d64fdb..f0f383b8a23 100644 --- a/packages/ckeditor5-image/src/imageupload/imageuploadcommand.js +++ b/packages/ckeditor5-image/src/imageupload/imageuploadcommand.js @@ -6,6 +6,7 @@ import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository'; import Command from '@ckeditor/ckeditor5-core/src/command'; import { insertImage, isImageAllowed } from '../image/utils'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * @module image/imageupload/imageuploadcommand @@ -63,9 +64,7 @@ export default class ImageUploadCommand extends Command { const fileRepository = editor.plugins.get( FileRepository ); - const filesToUpload = Array.isArray( options.file ) ? options.file : [ options.file ]; - - for ( const file of filesToUpload ) { + for ( const file of toArray( options.file ) ) { uploadImage( model, fileRepository, file ); } } diff --git a/packages/ckeditor5-media-embed/src/mediaregistry.js b/packages/ckeditor5-media-embed/src/mediaregistry.js index 7412107c2e5..3dcf4174969 100644 --- a/packages/ckeditor5-media-embed/src/mediaregistry.js +++ b/packages/ckeditor5-media-embed/src/mediaregistry.js @@ -12,6 +12,7 @@ import TooltipView from '@ckeditor/ckeditor5-ui/src/tooltip/tooltipview'; import IconView from '@ckeditor/ckeditor5-ui/src/icon/iconview'; import Template from '@ckeditor/ckeditor5-ui/src/template'; import { logWarning } from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; const mediaPlaceholderIconViewBox = '0 0 64 42'; @@ -113,11 +114,7 @@ export default class MediaRegistry { for ( const definition of this.providerDefinitions ) { const previewRenderer = definition.html; - let pattern = definition.url; - - if ( !Array.isArray( pattern ) ) { - pattern = [ pattern ]; - } + const pattern = toArray( definition.url ); for ( const subPattern of pattern ) { const match = this._getUrlMatches( url, subPattern ); diff --git a/packages/ckeditor5-table/package.json b/packages/ckeditor5-table/package.json index 9f97082fb7d..5712eda2fdd 100644 --- a/packages/ckeditor5-table/package.json +++ b/packages/ckeditor5-table/package.json @@ -12,6 +12,7 @@ "dependencies": { "@ckeditor/ckeditor5-core": "^23.1.0", "@ckeditor/ckeditor5-ui": "^23.1.0", + "@ckeditor/ckeditor5-utils": "^23.1.0", "@ckeditor/ckeditor5-widget": "^23.1.0", "lodash-es": "^4.17.15" }, @@ -29,7 +30,6 @@ "@ckeditor/ckeditor5-paragraph": "^23.1.0", "@ckeditor/ckeditor5-typing": "^23.1.0", "@ckeditor/ckeditor5-undo": "^23.1.0", - "@ckeditor/ckeditor5-utils": "^23.1.0", "json-diff": "^0.5.4" }, "engines": { diff --git a/packages/ckeditor5-table/src/converters/downcast.js b/packages/ckeditor5-table/src/converters/downcast.js index 12a535452e5..3f938248bb1 100644 --- a/packages/ckeditor5-table/src/converters/downcast.js +++ b/packages/ckeditor5-table/src/converters/downcast.js @@ -9,6 +9,7 @@ import TableWalker from './../tablewalker'; import { setHighlightHandling, toWidget, toWidgetEditable } from '@ckeditor/ckeditor5-widget/src/utils'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * Model table element to view table element conversion helper. @@ -314,8 +315,8 @@ function renameViewTableCell( tableCell, desiredCellElementName, conversionApi ) setHighlightHandling( renamedCell, viewWriter, - ( element, descriptor, writer ) => writer.addClass( normalizeToArray( descriptor.classes ), element ), - ( element, descriptor, writer ) => writer.removeClass( normalizeToArray( descriptor.classes ), element ) + ( element, descriptor, writer ) => writer.addClass( toArray( descriptor.classes ), element ), + ( element, descriptor, writer ) => writer.removeClass( toArray( descriptor.classes ), element ) ); viewWriter.insert( viewWriter.createPositionAfter( viewCell ), renamedCell ); @@ -363,8 +364,8 @@ function createViewTableCellElement( tableSlot, tableAttributes, insertPosition, setHighlightHandling( cellElement, conversionApi.writer, - ( element, descriptor, writer ) => writer.addClass( normalizeToArray( descriptor.classes ), element ), - ( element, descriptor, writer ) => writer.removeClass( normalizeToArray( descriptor.classes ), element ) + ( element, descriptor, writer ) => writer.addClass( toArray( descriptor.classes ), element ), + ( element, descriptor, writer ) => writer.removeClass( toArray( descriptor.classes ), element ) ); } @@ -521,7 +522,3 @@ function getViewTable( viewFigure ) { function hasAnyAttribute( element ) { return !![ ...element.getAttributeKeys() ].length; } - -function normalizeToArray( classes ) { - return Array.isArray( classes ) ? classes : [ classes ]; -} diff --git a/packages/ckeditor5-typing/tests/twostepcaretmovement.js b/packages/ckeditor5-typing/tests/twostepcaretmovement.js index 8a52f7b54dc..8ee13ad2b7c 100644 --- a/packages/ckeditor5-typing/tests/twostepcaretmovement.js +++ b/packages/ckeditor5-typing/tests/twostepcaretmovement.js @@ -14,6 +14,7 @@ import Position from '@ckeditor/ckeditor5-engine/src/model/position'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard'; import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; import '@ckeditor/ckeditor5-core/tests/_utils/assertions/attribute'; @@ -963,11 +964,10 @@ describe( 'TwoStepCaretMovement()', () => { else { const stepIndex = scenario.indexOf( step ); const stepString = `in step #${ stepIndex }`; - let caretPosition = step.caretPosition; - if ( caretPosition !== undefined ) { + if ( step.caretPosition !== undefined ) { // Normalize position - caretPosition = Array.isArray( step.caretPosition ) ? caretPosition : [ caretPosition ]; + const caretPosition = toArray( step.caretPosition ); expect( selection.getFirstPosition(), `in step #${ stepIndex }, selection's first position` ) .to.have.deep.property( 'path', caretPosition ); } diff --git a/packages/ckeditor5-ui/src/template.js b/packages/ckeditor5-ui/src/template.js index 98db107742a..da6f275d7f3 100644 --- a/packages/ckeditor5-ui/src/template.js +++ b/packages/ckeditor5-ui/src/template.js @@ -16,6 +16,7 @@ import View from './view'; import ViewCollection from './viewcollection'; import isNode from '@ckeditor/ckeditor5-utils/src/dom/isnode'; import { isObject, cloneDeepWith } from 'lodash-es'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; const xhtmlNs = 'http://www.w3.org/1999/xhtml'; @@ -1225,7 +1226,7 @@ function normalize( def ) { function normalizeAttributes( attributes ) { for ( const a in attributes ) { if ( attributes[ a ].value ) { - attributes[ a ].value = [].concat( attributes[ a ].value ); + attributes[ a ].value = toArray( attributes[ a ].value ); } arrayify( attributes, a ); @@ -1290,9 +1291,7 @@ function normalizePlainTextDefinition( def ) { // // @param {module:ui/template~TemplateDefinition} def function normalizeTextDefinition( def ) { - if ( !Array.isArray( def.text ) ) { - def.text = [ def.text ]; - } + def.text = toArray( def.text ); } // Wraps an entry in Object in an Array, if not already one. @@ -1312,9 +1311,7 @@ function normalizeTextDefinition( def ) { // @param {Object} obj // @param {String} key function arrayify( obj, key ) { - if ( !Array.isArray( obj[ key ] ) ) { - obj[ key ] = [ obj[ key ] ]; - } + obj[ key ] = toArray( obj[ key ] ); } // A helper which concatenates the value avoiding unwanted diff --git a/packages/ckeditor5-undo/tests/redocommand.js b/packages/ckeditor5-undo/tests/redocommand.js index a76a65fa83e..5548333a942 100644 --- a/packages/ckeditor5-undo/tests/redocommand.js +++ b/packages/ckeditor5-undo/tests/redocommand.js @@ -8,6 +8,7 @@ import Batch from '@ckeditor/ckeditor5-engine/src/model/batch'; import UndoCommand from '../src/undocommand'; import RedoCommand from '../src/redocommand'; import { itemAt, getText } from '@ckeditor/ckeditor5-engine/tests/model/_utils/utils'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; describe( 'RedoCommand', () => { let editor, model, root, redo, undo; @@ -28,7 +29,7 @@ describe( 'RedoCommand', () => { describe( 'RedoCommand', () => { describe( 'execute()', () => { - const p = pos => model.createPositionFromPath( root, [].concat( pos ) ); + const p = pos => model.createPositionFromPath( root, toArray( pos ) ); const r = ( a, b ) => model.createRange( p( a ), p( b ) ); let batch0, batch1, batch2; diff --git a/packages/ckeditor5-undo/tests/undocommand.js b/packages/ckeditor5-undo/tests/undocommand.js index b7056590b2d..0734f526699 100644 --- a/packages/ckeditor5-undo/tests/undocommand.js +++ b/packages/ckeditor5-undo/tests/undocommand.js @@ -7,6 +7,7 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit import Batch from '@ckeditor/ckeditor5-engine/src/model/batch'; import UndoCommand from '../src/undocommand'; import { itemAt, getText } from '@ckeditor/ckeditor5-engine/tests/model/_utils/utils'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; describe( 'UndoCommand', () => { let editor, model, doc, root, undo; @@ -27,7 +28,7 @@ describe( 'UndoCommand', () => { } ); describe( 'UndoCommand', () => { - const p = pos => model.createPositionFromPath( root, [].concat( pos ) ); + const p = pos => model.createPositionFromPath( root, toArray( pos ) ); const r = ( a, b ) => model.createRange( p( a ), p( b ) ); describe( 'execute()', () => { diff --git a/packages/ckeditor5-utils/src/locale.js b/packages/ckeditor5-utils/src/locale.js index 6927d012912..598192e472a 100644 --- a/packages/ckeditor5-utils/src/locale.js +++ b/packages/ckeditor5-utils/src/locale.js @@ -9,6 +9,7 @@ /* globals console */ +import toArray from './toarray'; import { _translate } from './translation-service'; const RTL_LANGUAGE_CODES = [ 'ar', 'fa', 'he', 'ku', 'ug' ]; @@ -153,9 +154,7 @@ export default class Locale { * @returns {String} */ _t( message, values = [] ) { - if ( !Array.isArray( values ) ) { - values = [ values ]; - } + values = toArray( values ); if ( typeof message === 'string' ) { message = { string: message }; diff --git a/packages/ckeditor5-utils/src/toarray.js b/packages/ckeditor5-utils/src/toarray.js new file mode 100644 index 00000000000..520f68fc417 --- /dev/null +++ b/packages/ckeditor5-utils/src/toarray.js @@ -0,0 +1,18 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * @module utils/toarray + */ + +/** + * Transforms any value to an array, if it is not already one. If provided value is already an array, it is returned unchanged. + * + * @param {*} [data] Value to transform to an array. + * @returns {Array} Array created from data. + */ +export default function toArray( data = [] ) { + return Array.isArray( data ) ? data : [ data ]; +} diff --git a/packages/ckeditor5-utils/tests/toarray.js b/packages/ckeditor5-utils/tests/toarray.js new file mode 100644 index 00000000000..2c8871b8f10 --- /dev/null +++ b/packages/ckeditor5-utils/tests/toarray.js @@ -0,0 +1,33 @@ +/** + * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +import toArray from '../src/toarray'; + +describe( 'utils', () => { + describe( 'toArray', () => { + it( 'should wrap non-array values in an array', () => { + expect( toArray( 0 ) ).to.deep.equal( [ 0 ] ); + expect( toArray( 1 ) ).to.deep.equal( [ 1 ] ); + expect( toArray( '' ) ).to.deep.equal( [ '' ] ); + expect( toArray( 'foo' ) ).to.deep.equal( [ 'foo' ] ); + expect( toArray( false ) ).to.deep.equal( [ false ] ); + expect( toArray( true ) ).to.deep.equal( [ true ] ); + expect( toArray( null ) ).to.deep.equal( [ null ] ); + expect( toArray( {} ) ).to.deep.equal( [ {} ] ); + } ); + + it( 'should return array values by reference and unchanged', () => { + const array = toArray( [ 'foo' ] ); + + expect( toArray( array ) ).to.equal( array ); + expect( toArray( array ) ).to.deep.equal( [ 'foo' ] ); + } ); + + it( 'should return an empty array when no argument is given or it is `undefined`', () => { + expect( toArray() ).to.deep.equal( [] ); + expect( toArray( undefined ) ).to.deep.equal( [] ); + } ); + } ); +} ); diff --git a/packages/ckeditor5-watchdog/package.json b/packages/ckeditor5-watchdog/package.json index 830c8d472a9..c77737249cd 100644 --- a/packages/ckeditor5-watchdog/package.json +++ b/packages/ckeditor5-watchdog/package.json @@ -9,14 +9,14 @@ "ckeditor5-lib" ], "dependencies": { + "@ckeditor/ckeditor5-utils": "^23.1.0", "lodash-es": "^4.17.15" }, "devDependencies": { "@ckeditor/ckeditor5-core": "^23.1.0", "@ckeditor/ckeditor5-editor-classic": "^23.1.0", "@ckeditor/ckeditor5-engine": "^23.1.0", - "@ckeditor/ckeditor5-paragraph": "^23.1.0", - "@ckeditor/ckeditor5-utils": "^23.1.0" + "@ckeditor/ckeditor5-paragraph": "^23.1.0" }, "engines": { "node": ">=12.0.0", diff --git a/packages/ckeditor5-watchdog/src/contextwatchdog.js b/packages/ckeditor5-watchdog/src/contextwatchdog.js index d93f6197192..4012c184b9a 100644 --- a/packages/ckeditor5-watchdog/src/contextwatchdog.js +++ b/packages/ckeditor5-watchdog/src/contextwatchdog.js @@ -13,6 +13,7 @@ import Watchdog from './watchdog'; import EditorWatchdog from './editorwatchdog'; import areConnectedThroughProperties from './utils/areconnectedthroughproperties'; import getSubNodes from './utils/getsubnodes'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; /** * A watchdog for the {@link module:core/context~Context} class. @@ -234,9 +235,7 @@ export default class ContextWatchdog extends Watchdog { * @returns {Promise} */ add( itemConfigurationOrItemConfigurations ) { - const itemConfigurations = Array.isArray( itemConfigurationOrItemConfigurations ) ? - itemConfigurationOrItemConfigurations : - [ itemConfigurationOrItemConfigurations ]; + const itemConfigurations = toArray( itemConfigurationOrItemConfigurations ); return this._actionQueue.enqueue( () => { if ( this.state === 'destroyed' ) { @@ -310,9 +309,7 @@ export default class ContextWatchdog extends Watchdog { * @returns {Promise} */ remove( itemIdOrItemIds ) { - const itemIds = Array.isArray( itemIdOrItemIds ) ? - itemIdOrItemIds : - [ itemIdOrItemIds ]; + const itemIds = toArray( itemIdOrItemIds ); return this._actionQueue.enqueue( () => { return Promise.all( itemIds.map( itemId => { diff --git a/packages/ckeditor5-widget/src/utils.js b/packages/ckeditor5-widget/src/utils.js index 5fd03b9034b..ba6070115af 100644 --- a/packages/ckeditor5-widget/src/utils.js +++ b/packages/ckeditor5-widget/src/utils.js @@ -13,6 +13,7 @@ import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect'; import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview'; import global from '@ckeditor/ckeditor5-utils/src/dom/global'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; import dragHandleIcon from '../theme/icons/drag-handle.svg'; import { getTypeAroundFakeCaretPosition } from './widgettypearound/utils'; @@ -124,16 +125,11 @@ export function toWidget( element, writer, options = {} ) { setHighlightHandling( element, writer, - ( element, descriptor, writer ) => writer.addClass( normalizeToArray( descriptor.classes ), element ), - ( element, descriptor, writer ) => writer.removeClass( normalizeToArray( descriptor.classes ), element ) + ( element, descriptor, writer ) => writer.addClass( toArray( descriptor.classes ), element ), + ( element, descriptor, writer ) => writer.removeClass( toArray( descriptor.classes ), element ) ); return element; - - // Normalizes CSS class in descriptor that can be provided in form of an array or a string. - function normalizeToArray( classes ) { - return Array.isArray( classes ) ? classes : [ classes ]; - } } /** diff --git a/packages/ckeditor5-widget/tests/widget.js b/packages/ckeditor5-widget/tests/widget.js index dc2ad1a6026..066eef7de12 100644 --- a/packages/ckeditor5-widget/tests/widget.js +++ b/packages/ckeditor5-widget/tests/widget.js @@ -17,6 +17,7 @@ import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventd import { setData as setModelData, getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard'; +import toArray from '@ckeditor/ckeditor5-utils/src/toarray'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'Widget', () => { @@ -808,10 +809,7 @@ describe( 'Widget', () => { it( name, () => { testUtils.sinon.stub( editor.locale, 'contentLanguageDirection' ).value( contentLanguageDirection ); - if ( !Array.isArray( actions ) ) { - actions = [ actions ]; - } - + actions = toArray( actions ); actions = actions.map( action => { if ( typeof action === 'object' ) { return action; From e177695eff55c46de469dcd8bc9e892deee42d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Smyrek?= Date: Thu, 12 Nov 2020 12:26:20 +0100 Subject: [PATCH 2/5] Simplified `_addClass()` method --- packages/ckeditor5-engine/src/view/element.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ckeditor5-engine/src/view/element.js b/packages/ckeditor5-engine/src/view/element.js index 52681e38af9..6fb047b890f 100644 --- a/packages/ckeditor5-engine/src/view/element.js +++ b/packages/ckeditor5-engine/src/view/element.js @@ -725,7 +725,9 @@ export default class Element extends Node { _addClass( className ) { this._fireChange( 'attributes', this ); - toArray( className ).forEach( name => this._classes.add( name ) ); + for ( const name of toArray( className ) ) { + this._classes.add( name ); + } } /** From f89d200a4ec191f47b9a7088d5076fc0163d7846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Smyrek?= Date: Thu, 12 Nov 2020 12:30:08 +0100 Subject: [PATCH 3/5] Simplified `_removeClass()` and `_removeStyle()` methods --- packages/ckeditor5-engine/src/view/element.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/ckeditor5-engine/src/view/element.js b/packages/ckeditor5-engine/src/view/element.js index 6fb047b890f..4967b09294d 100644 --- a/packages/ckeditor5-engine/src/view/element.js +++ b/packages/ckeditor5-engine/src/view/element.js @@ -744,7 +744,9 @@ export default class Element extends Node { _removeClass( className ) { this._fireChange( 'attributes', this ); - toArray( className ).forEach( name => this._classes.delete( name ) ); + for ( const name of toArray( className ) ) { + this._classes.delete( name ); + } } /** @@ -790,7 +792,9 @@ export default class Element extends Node { _removeStyle( property ) { this._fireChange( 'attributes', this ); - toArray( property ).forEach( name => this._styles.remove( name ) ); + for ( const name of toArray( property ) ) { + this._styles.remove( name ); + } } /** From 2627e7a213ae8828cc5443feba5cc26adba1d194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Smyrek?= Date: Thu, 19 Nov 2020 10:43:09 +0100 Subject: [PATCH 4/5] Default value in toArray() is not needed --- packages/ckeditor5-utils/src/toarray.js | 4 ++-- packages/ckeditor5-utils/tests/toarray.js | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/ckeditor5-utils/src/toarray.js b/packages/ckeditor5-utils/src/toarray.js index 520f68fc417..641b680c019 100644 --- a/packages/ckeditor5-utils/src/toarray.js +++ b/packages/ckeditor5-utils/src/toarray.js @@ -10,9 +10,9 @@ /** * Transforms any value to an array, if it is not already one. If provided value is already an array, it is returned unchanged. * - * @param {*} [data] Value to transform to an array. + * @param {*} data Value to transform to an array. * @returns {Array} Array created from data. */ -export default function toArray( data = [] ) { +export default function toArray( data ) { return Array.isArray( data ) ? data : [ data ]; } diff --git a/packages/ckeditor5-utils/tests/toarray.js b/packages/ckeditor5-utils/tests/toarray.js index 2c8871b8f10..f0c84138641 100644 --- a/packages/ckeditor5-utils/tests/toarray.js +++ b/packages/ckeditor5-utils/tests/toarray.js @@ -16,6 +16,7 @@ describe( 'utils', () => { expect( toArray( true ) ).to.deep.equal( [ true ] ); expect( toArray( null ) ).to.deep.equal( [ null ] ); expect( toArray( {} ) ).to.deep.equal( [ {} ] ); + expect( toArray() ).to.deep.equal( [ undefined ] ); } ); it( 'should return array values by reference and unchanged', () => { @@ -24,10 +25,5 @@ describe( 'utils', () => { expect( toArray( array ) ).to.equal( array ); expect( toArray( array ) ).to.deep.equal( [ 'foo' ] ); } ); - - it( 'should return an empty array when no argument is given or it is `undefined`', () => { - expect( toArray() ).to.deep.equal( [] ); - expect( toArray( undefined ) ).to.deep.equal( [] ); - } ); } ); } ); From 81c10ea10bdbfbdc02e8ffd38523fade5750b5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Smyrek?= Date: Thu, 19 Nov 2020 10:44:33 +0100 Subject: [PATCH 5/5] Improved description --- packages/ckeditor5-utils/src/toarray.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ckeditor5-utils/src/toarray.js b/packages/ckeditor5-utils/src/toarray.js index 641b680c019..171de7b0b9c 100644 --- a/packages/ckeditor5-utils/src/toarray.js +++ b/packages/ckeditor5-utils/src/toarray.js @@ -8,7 +8,7 @@ */ /** - * Transforms any value to an array, if it is not already one. If provided value is already an array, it is returned unchanged. + * Transforms any value to an array. If the provided value is already an array, it is returned unchanged. * * @param {*} data Value to transform to an array. * @returns {Array} Array created from data.