@ckeditor/ckeditor5-alignment
Advanced tools
Comparing version 0.0.1 to 1.0.0-beta.1
@@ -5,3 +5,4 @@ { | ||
"Align center": "Toolbar button tooltip for aligning text to center.", | ||
"Justify": "Toolbar button tooltip for making text justified." | ||
"Justify": "Toolbar button tooltip for making text justified.", | ||
"Text alignment": "Dropdown button tooltip for the text alignment feature." | ||
} |
@@ -5,3 +5,3 @@ Software License Agreement | ||
**CKEditor 5 Text Alignment Feature** – https://github.com/ckeditor/ckeditor5-alignment <br> | ||
Copyright (c) 2003-2017, [CKSource](http://cksource.com) Frederico Knabben. All rights reserved. | ||
Copyright (c) 2003-2018, [CKSource](http://cksource.com) Frederico Knabben. All rights reserved. | ||
@@ -8,0 +8,0 @@ Licensed under the terms of any of the following licenses at your choice: |
{ | ||
"name": "@ckeditor/ckeditor5-alignment", | ||
"version": "0.0.1", | ||
"version": "1.0.0-beta.1", | ||
"description": "Text alignment feature for CKEditor 5.", | ||
@@ -10,20 +10,21 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-core": "*", | ||
"@ckeditor/ckeditor5-engine": "*", | ||
"@ckeditor/ckeditor5-ui": "*" | ||
"@ckeditor/ckeditor5-core": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-engine": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-ui": "^1.0.0-beta.1" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-block-quote": "*", | ||
"@ckeditor/ckeditor5-editor-classic": "*", | ||
"@ckeditor/ckeditor5-enter": "*", | ||
"@ckeditor/ckeditor5-heading": "*", | ||
"@ckeditor/ckeditor5-image": "*", | ||
"@ckeditor/ckeditor5-list": "*", | ||
"@ckeditor/ckeditor5-paragraph": "*", | ||
"@ckeditor/ckeditor5-typing": "*", | ||
"@ckeditor/ckeditor5-utils": "*", | ||
"eslint": "^4.8.0", | ||
"@ckeditor/ckeditor5-block-quote": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-cloudservices": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-editor-classic": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-enter": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-heading": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-image": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-list": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-paragraph": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-typing": "^1.0.0-beta.1", | ||
"@ckeditor/ckeditor5-utils": "^1.0.0-beta.1", | ||
"eslint": "^4.15.0", | ||
"eslint-config-ckeditor5": "^1.0.7", | ||
"husky": "^0.14.3", | ||
"lint-staged": "^4.2.3" | ||
"lint-staged": "^6.0.0" | ||
}, | ||
@@ -30,0 +31,0 @@ "engines": { |
@@ -7,3 +7,5 @@ CKEditor 5 text alignment feature | ||
[![Build Status](https://travis-ci.org/ckeditor/ckeditor5-alignment.svg?branch=master)](https://travis-ci.org/ckeditor/ckeditor5-alignment) | ||
[![Test Coverage](https://codeclimate.com/github/ckeditor/ckeditor5-alignment/badges/coverage.svg)](https://codeclimate.com/github/ckeditor/ckeditor5-alignment/coverage) | ||
[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)](https://www.browserstack.com/automate/public-build/d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0) | ||
[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5-alignment/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5-alignment?branch=master) | ||
<br> | ||
[![Dependency Status](https://david-dm.org/ckeditor/ckeditor5-alignment/status.svg)](https://david-dm.org/ckeditor/ckeditor5-alignment) | ||
@@ -10,0 +12,0 @@ [![devDependency Status](https://david-dm.org/ckeditor/ckeditor5-alignment/dev-status.svg)](https://david-dm.org/ckeditor/ckeditor5-alignment?type=dev) |
/** | ||
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
@@ -16,6 +16,9 @@ */ | ||
/** | ||
* The alignment plugin. | ||
* The text alignment plugin. | ||
* | ||
* It requires {@link module:alignment/alignmentediting~AlignmentEditing} and {@link module:alignment/alignmentui~AlignmentUI} plugins. | ||
* It loads the {@link module:alignment/alignmentediting~AlignmentEditing} and | ||
* {@link module:alignment/alignmentui~AlignmentUI} plugins. | ||
* | ||
* Read more about the feature on the {@glink api/alignment text alignment package} page. | ||
* | ||
* @extends module:core/plugin~Plugin | ||
@@ -38,1 +41,48 @@ */ | ||
} | ||
/** | ||
* The configuration of the {@link module:alignment/alignment~Alignment alignment feature}. | ||
* | ||
* Read more in {@link module:alignment/alignment~AlignmentConfig}. | ||
* | ||
* @member {module:alignment/alignment~AlignmentConfig} module:core/editor/editorconfig~EditorConfig#alignment | ||
*/ | ||
/** | ||
* The configuration of the {@link module:alignment/alignment~Alignment alignment feature}. | ||
* | ||
* ClassicEditor | ||
* .create( editorElement, { | ||
* alignment: { | ||
* options: [ 'left', 'right' ] | ||
* } | ||
* } ) | ||
* .then( ... ) | ||
* .catch( ... ); | ||
* | ||
* See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}. | ||
* | ||
* @interface AlignmentConfig | ||
*/ | ||
/** | ||
* Available alignment options. | ||
* | ||
* The available options are: `'left'`, `'right'`, `'center'` and `'justify'`. Other values are ignored. | ||
* | ||
* **Note:** It is recommended to always use `'left'` as it is the default value which the user should | ||
* normally be able to choose. | ||
* | ||
* ClassicEditor | ||
* .create( editorElement, { | ||
* alignment: { | ||
* options: [ 'left', 'right' ] | ||
* } | ||
* } ) | ||
* .then( ... ) | ||
* .catch( ... ); | ||
* | ||
* See a demo of {@glink features/text-alignment#configuring-alignment-options custom alignment options}. | ||
* | ||
* @member {Array.<String>} module:alignment/alignment~AlignmentConfig#options | ||
*/ |
/** | ||
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
@@ -13,2 +13,6 @@ */ | ||
import { isDefault } from './utils'; | ||
const ALIGNMENT = 'alignment'; | ||
/** | ||
@@ -21,73 +25,51 @@ * The alignment command plugin. | ||
/** | ||
* Creates an instance of the command. | ||
* | ||
* @param {module:core/editor/editor~Editor} editor The editor instance. | ||
* @param {'left'|'right'|'center'|'justify'} type Alignment type to be handled by this command. | ||
* @param {Boolean} isDefault Indicates if command is of default type. | ||
* @inheritDoc | ||
*/ | ||
constructor( editor, type, isDefault ) { | ||
super( editor ); | ||
refresh() { | ||
const firstBlock = first( this.editor.model.document.selection.getSelectedBlocks() ); | ||
/** | ||
* The type of the list created by the command. | ||
* | ||
* @readonly | ||
* @member {'left'|'right'|'center'|'justify'} | ||
*/ | ||
this.type = type; | ||
// As first check whether to enable or disable the command as the value will always be false if the command cannot be enabled. | ||
this.isEnabled = !!firstBlock && this._canBeAligned( firstBlock ); | ||
/** | ||
* Whether this command has default type. | ||
* A value of the current block's alignment. | ||
* | ||
* @readonly | ||
* @private | ||
* @member {Boolean} | ||
*/ | ||
this._isDefault = isDefault; | ||
/** | ||
* A flag indicating whether the command is active, which means that the selection starts in a block | ||
* that has defined alignment of the same type. | ||
* | ||
* @observable | ||
* @readonly | ||
* @member {Boolean} #value | ||
* @member {String} #value | ||
*/ | ||
this.value = ( this.isEnabled && firstBlock.hasAttribute( 'alignment' ) ) ? firstBlock.getAttribute( 'alignment' ) : 'left'; | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
refresh() { | ||
const firstBlock = first( this.editor.document.selection.getSelectedBlocks() ); | ||
// As first check whether to enable or disable command as value will be always false if command cannot be enabled. | ||
this.isEnabled = !!firstBlock && this._canBeAligned( firstBlock ); | ||
this.value = this._getValue( firstBlock ); | ||
} | ||
/** | ||
* Executes the command. | ||
* Executes the command. Applies the alignment `value` to the selected blocks. | ||
* If no `value` is passed, is a default one or is equal to currently selected block's alignment attribute, | ||
* it will remove the attribute from the selected blocks. | ||
* | ||
* @protected | ||
* @param {Object} [options] Options for the executed command. | ||
* @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps. | ||
* A new batch will be created if this option is not set. | ||
* @param {String} [options.value] The value to apply. | ||
* @fires execute | ||
*/ | ||
execute( options = {} ) { | ||
const editor = this.editor; | ||
const document = editor.document; | ||
const model = editor.model; | ||
const doc = model.document; | ||
document.enqueueChanges( () => { | ||
const batch = options.batch || document.batch(); | ||
const value = options.value; | ||
model.change( writer => { | ||
// Get only those blocks from selected that can have alignment set | ||
const blocks = Array.from( document.selection.getSelectedBlocks() ).filter( block => this._canBeAligned( block ) ); | ||
const blocks = Array.from( doc.selection.getSelectedBlocks() ).filter( block => this._canBeAligned( block ) ); | ||
const currentAlignment = blocks[ 0 ].getAttribute( 'alignment' ); | ||
// Remove alignment attribute if current alignment is as selected or is default one. | ||
// Default alignment should not be stored in model as it will bloat model data. | ||
if ( this.value || this._isDefault ) { | ||
removeAlignmentFromSelection( blocks, batch ); | ||
// Remove alignment attribute if current alignment is: | ||
// - default (should not be stored in model as it will bloat model data) | ||
// - equal to currently set | ||
// - or no value is passed - denotes default alignment. | ||
const removeAlignment = isDefault( value ) || currentAlignment === value || !value; | ||
if ( removeAlignment ) { | ||
removeAlignmentFromSelection( blocks, writer ); | ||
} else { | ||
setAlignmentOnSelection( blocks, batch, this.type ); | ||
setAlignmentOnSelection( blocks, writer, value ); | ||
} | ||
@@ -98,37 +80,11 @@ } ); | ||
/** | ||
* Checks whether block can have aligned set. | ||
* Checks whether a block can have alignment set. | ||
* | ||
* @private | ||
* @param {module:engine/model/element~Element} block A block to be checked. | ||
* @returns {Boolean} | ||
* @private | ||
*/ | ||
_canBeAligned( block ) { | ||
const schema = this.editor.document.schema; | ||
// Check if adding alignment attribute to selected block is allowed. | ||
return schema.check( { | ||
name: block.name, | ||
// Apparently I must pass current attributes as otherwise adding alignment on listItem will fail. | ||
attributes: [ ...block.getAttributeKeys(), 'alignment' ] | ||
} ); | ||
return this.editor.model.schema.checkAttribute( block, ALIGNMENT ); | ||
} | ||
/** | ||
* Checks the command's {@link #value}. | ||
* | ||
* @private | ||
* @param {module:engine/model/element~Element} firstBlock A first block in selection to be checked. | ||
* @returns {Boolean} The current value. | ||
*/ | ||
_getValue( firstBlock ) { | ||
// The #_checkEnabled is checked as first so if command is disabled it's value is also false. | ||
if ( !this.isEnabled || !firstBlock ) { | ||
return false; | ||
} | ||
const selectionAlignment = firstBlock.getAttribute( 'alignment' ); | ||
// Command's value will be set when commands type is matched in selection or the selection is default one. | ||
return selectionAlignment ? selectionAlignment === this.type : this._isDefault; | ||
} | ||
} | ||
@@ -138,5 +94,5 @@ | ||
// @private | ||
function removeAlignmentFromSelection( blocks, batch ) { | ||
function removeAlignmentFromSelection( blocks, writer ) { | ||
for ( const block of blocks ) { | ||
batch.removeAttribute( 'alignment', block ); | ||
writer.removeAttribute( ALIGNMENT, block ); | ||
} | ||
@@ -147,6 +103,6 @@ } | ||
// @private | ||
function setAlignmentOnSelection( blocks, batch, type ) { | ||
function setAlignmentOnSelection( blocks, writer, alignment ) { | ||
for ( const block of blocks ) { | ||
batch.setAttribute( 'alignment', type, block ); | ||
writer.setAttribute( ALIGNMENT, alignment, block ); | ||
} | ||
} |
/** | ||
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
@@ -13,9 +13,7 @@ */ | ||
import AlignmentCommand from './alignmentcommand'; | ||
import { isDefault, isSupported, supportedOptions } from './utils'; | ||
import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildviewconverter'; | ||
import { eventNameToConsumableType } from '@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters'; | ||
import upperFirst from '@ckeditor/ckeditor5-utils/src/lib/lodash/upperFirst'; | ||
/** | ||
* The alignment editing feature. It introduces the {@link module:alignment/alignmentcommand~AlignmentCommand command} and adds | ||
* the `alignment` attribute of block elements in the {@link module:engine/model/model~Model model}. | ||
* @extends module:core/plugin~Plugin | ||
@@ -30,21 +28,8 @@ */ | ||
editor.config.define( 'alignment', { styles: [ ...this.constructor.supportedStyles ] } ); | ||
editor.config.define( 'alignment', { | ||
options: [ ...supportedOptions ] | ||
} ); | ||
} | ||
/** | ||
* List of supported alignment styles: | ||
* - left | ||
* - right | ||
* - center | ||
* - justify | ||
* | ||
* @static | ||
* @readonly | ||
* @member {Array.<String>} module:alignment/alignmentediting~AlignmentEditing.supportedStyles | ||
*/ | ||
static get supportedStyles() { | ||
return [ 'left', 'right', 'center', 'justify' ]; | ||
} | ||
/** | ||
* @inheritDoc | ||
@@ -54,150 +39,39 @@ */ | ||
const editor = this.editor; | ||
const doc = editor.document; | ||
const schema = doc.schema; | ||
const data = editor.data; | ||
const editing = editor.editing; | ||
const schema = editor.model.schema; | ||
const enabledStyles = editor.config.get( 'alignment.styles' ); | ||
// Filter out unsupported options. | ||
const enabledOptions = editor.config.get( 'alignment.options' ).filter( isSupported ); | ||
// Allow alignment attribute on all blocks. | ||
schema.allow( { name: '$block', attributes: 'alignment' } ); | ||
schema.extend( '$block', { allowAttributes: 'alignment' } ); | ||
attributeToStyleConverter( | ||
[ data.modelToView, editing.modelToView ], | ||
'alignment', | ||
attribute => ( { 'text-align': attribute } ), | ||
() => [ 'text-align' ] | ||
); | ||
const definition = _buildDefinition( enabledOptions.filter( option => !isDefault( option ) ) ); | ||
// Convert `text-align` style property from element to model attribute alignment. | ||
buildViewConverter() | ||
.for( data.viewToModel ) | ||
.fromAttribute( 'style', /text-align/ ) | ||
.toAttribute( viewElement => { | ||
const textAlign = viewElement.getStyle( 'text-align' ); | ||
editor.conversion.attributeToAttribute( definition ); | ||
// Do not convert empty, default or unknown alignment values. | ||
if ( !textAlign || isDefault( textAlign ) || !enabledStyles.includes( textAlign ) ) { | ||
return; | ||
} | ||
return { key: 'alignment', value: textAlign }; | ||
} ); | ||
// Add only enabled & supported commands. | ||
enabledStyles | ||
.filter( isSupported ) | ||
.forEach( style => { | ||
editor.commands.add( AlignmentEditing.commandName( style ), new AlignmentCommand( editor, style, isDefault( style ) ) ); | ||
} ); | ||
editor.commands.add( 'alignment', new AlignmentCommand( editor ) ); | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
afterInit() { | ||
const schema = this.editor.document.schema; | ||
// Disallow alignment on caption elements. | ||
if ( schema.hasItem( 'caption' ) ) { | ||
schema.disallow( { name: 'caption', attributes: 'alignment' } ); | ||
} | ||
} | ||
/** | ||
* Helper function that returns command name for given style. May produce unknown commands if passed style is not | ||
* in {@link module:alignment/alignmentediting~AlignmentEditing.supportedStyles}. | ||
* | ||
* @param {String} style | ||
* @returns {String} | ||
*/ | ||
static commandName( style ) { | ||
return `align${ upperFirst( style ) }`; | ||
} | ||
} | ||
/** | ||
* Checks whether passed style is supported by {@link module:alignment/alignmentediting~AlignmentEditing}. | ||
* | ||
* @param {String} style Style value to check. | ||
* @returns {Boolean} | ||
*/ | ||
export function isSupported( style ) { | ||
return AlignmentEditing.supportedStyles.includes( style ); | ||
} | ||
// Defines attribute to style converters. | ||
// Utility function responsible for building converter definition. | ||
// @private | ||
function attributeToStyleConverter( dispatchers, modelAttributeName, setStyleFn, removeStyleFn ) { | ||
for ( const dispatcher of dispatchers ) { | ||
dispatcher.on( `addAttribute:${ modelAttributeName }`, setStyle( setStyleFn ) ); | ||
dispatcher.on( `changeAttribute:${ modelAttributeName }`, setStyle( setStyleFn ) ); | ||
dispatcher.on( `removeAttribute:${ modelAttributeName }`, removeStyle( removeStyleFn ) ); | ||
} | ||
} | ||
// Dispatcher handler responsible for setting style to a view element. | ||
// @private | ||
function setStyle( setStyleFn ) { | ||
return ( evt, data, consumable, conversionApi ) => { | ||
if ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) { | ||
return; | ||
} | ||
const styles = setStyleFn( data.attributeNewValue ); | ||
conversionApi.mapper.toViewElement( data.item ).setStyle( styles ); | ||
function _buildDefinition( options ) { | ||
const definition = { | ||
model: { | ||
key: 'alignment', | ||
values: options.slice() | ||
}, | ||
view: {} | ||
}; | ||
} | ||
// Dispatcher handler responsible for removing style attributes from a view element. | ||
// @private | ||
function removeStyle( removeStyleFn ) { | ||
return ( evt, data, consumable, conversionApi ) => { | ||
if ( !consumable.consume( data.item, eventNameToConsumableType( evt.name ) ) ) { | ||
return; | ||
} | ||
for ( const option of options ) { | ||
definition.view[ option ] = { | ||
key: 'style', | ||
value: { | ||
'text-align': option | ||
} | ||
}; | ||
} | ||
const styles = removeStyleFn(); | ||
const viewElement = conversionApi.mapper.toViewElement( data.item ); | ||
viewElement.removeStyle( ...styles ); | ||
}; | ||
return definition; | ||
} | ||
// Check whether alignment is default one. | ||
// @protected | ||
export function isDefault( textAlign ) { | ||
// Right now only RTL is supported so 'left' value is always default one. | ||
return textAlign === 'left'; | ||
} | ||
/** | ||
* The configuration of the {@link module:alignment/alignmentediting~AlignmentEditing Alignment feature}. | ||
* | ||
* Read more in {@link module:alignment/alignmentediting~AlignmentEditingConfig}. | ||
* | ||
* @member {module:alignment/alignmentediting~AlignmentEditingConfig} module:core/editor/editorconfig~EditorConfig#alignment | ||
*/ | ||
/** | ||
* The configuration of the {@link module:alignment/alignmentediting~AlignmentEditing Alignment feature}. | ||
* | ||
* ClassicEditor | ||
* .create( editorElement, { | ||
* alignment: { | ||
* styles: [ 'left', 'right' ] | ||
* } | ||
* } ) | ||
* .then( ... ) | ||
* .catch( ... ); | ||
* | ||
* See {@link module:core/editor/editorconfig~EditorConfig all editor options}. | ||
* | ||
* @interface AlignmentEditingConfig | ||
*/ | ||
/** | ||
* Enabled alignment styles from supported styles: `left`, `right`, `center` and `justify`. Other values are ignored. | ||
* | ||
* @member {String} module:alignment/alignmentediting~AlignmentEditingConfig#styles | ||
*/ |
/** | ||
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
@@ -11,5 +11,7 @@ */ | ||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; | ||
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; | ||
import { createDropdown, addToolbarToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; | ||
import { isSupported } from './utils'; | ||
import alignLeftIcon from '../theme/icons/align-left.svg'; | ||
@@ -19,5 +21,2 @@ import alignRightIcon from '../theme/icons/align-right.svg'; | ||
import alignJustifyIcon from '../theme/icons/align-justify.svg'; | ||
import AlignmentEditing, { isSupported } from './alignmentediting'; | ||
import createButtonDropdown from '@ckeditor/ckeditor5-ui/src/dropdown/button/createbuttondropdown'; | ||
import Model from '../../ckeditor5-ui/src/model'; | ||
@@ -32,5 +31,6 @@ const icons = new Map( [ | ||
/** | ||
* The default Alignment UI plugin. | ||
* The default alignment UI plugin. | ||
* | ||
* It introduces the `'alignLeft'`, `'alignRight'`, `'alignCenter'` and `'alignJustify'` buttons. | ||
* It introduces the `'alignment:left'`, `'alignment:right'`, `'alignment:center'` and `'alignment:justify'` buttons | ||
* and the `'alignment'` dropdown. | ||
* | ||
@@ -41,11 +41,11 @@ * @extends module:core/plugin~Plugin | ||
/** | ||
* Returns the localized style titles provided by the plugin. | ||
* Returns the localized option titles provided by the plugin. | ||
* | ||
* The following localized titles corresponding with | ||
* {@link module:alignment/alignmentediting~AlignmentEditingConfig#styles} are available: | ||
* {@link module:alignment/alignment~AlignmentConfig#options} are available: | ||
* | ||
* * `'Left'`, | ||
* * `'Right'`, | ||
* * `'Center'`, | ||
* * `'Justify'` | ||
* * `'left'`, | ||
* * `'right'`, | ||
* * `'center'`, | ||
* * `'justify'`. | ||
* | ||
@@ -55,3 +55,3 @@ * @readonly | ||
*/ | ||
get localizedStylesTitles() { | ||
get localizedOptionTitles() { | ||
const t = this.editor.t; | ||
@@ -70,9 +70,2 @@ | ||
*/ | ||
static get requires() { | ||
return [ AlignmentEditing ]; | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
static get pluginName() { | ||
@@ -89,26 +82,50 @@ return 'AlignmentUI'; | ||
const t = editor.t; | ||
const styles = editor.config.get( 'alignment.styles' ); | ||
const options = editor.config.get( 'alignment.options' ); | ||
styles | ||
options | ||
.filter( isSupported ) | ||
.forEach( style => this._addButton( style ) ); | ||
.forEach( option => this._addButton( option ) ); | ||
componentFactory.add( 'alignmentDropdown', locale => { | ||
const buttons = styles.map( style => { | ||
return componentFactory.create( AlignmentEditing.commandName( style ) ); | ||
} ); | ||
componentFactory.add( 'alignment', locale => { | ||
const dropdownView = createDropdown( locale ); | ||
const model = new Model( { | ||
// Add existing alignment buttons to dropdown's toolbar. | ||
const buttons = options.map( option => componentFactory.create( `alignment:${ option }` ) ); | ||
addToolbarToDropdown( dropdownView, buttons ); | ||
// Configure dropdown properties an behavior. | ||
dropdownView.buttonView.set( { | ||
label: t( 'Text alignment' ), | ||
defaultIcon: alignLeftIcon, | ||
withText: false, | ||
isVertical: true, | ||
tooltip: true, | ||
toolbarClassName: 'ck-editor-toolbar', | ||
buttons | ||
tooltip: true | ||
} ); | ||
const dropdown = createButtonDropdown( model, locale ); | ||
dropdownView.toolbarView.isVertical = true; | ||
return dropdown; | ||
dropdownView.extendTemplate( { | ||
attributes: { | ||
class: 'ck-alignment-dropdown' | ||
} | ||
} ); | ||
// The default icon is align left as we do not support RTL yet (see #3). | ||
const defaultIcon = alignLeftIcon; | ||
// Change icon to reflect current selection's alignment. | ||
dropdownView.buttonView.bind( 'icon' ).toMany( buttons, 'isOn', ( ...areActive ) => { | ||
// Get the index of an active button. | ||
const index = areActive.findIndex( value => value ); | ||
// If none of the commands is active, display either defaultIcon or the first button's icon. | ||
if ( index < 0 ) { | ||
return defaultIcon; | ||
} | ||
// Return active button's icon. | ||
return buttons[ index ].icon; | ||
} ); | ||
// Enable button if any of the buttons is enabled. | ||
dropdownView.bind( 'isEnabled' ).toMany( buttons, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) ); | ||
return dropdownView; | ||
} ); | ||
@@ -118,19 +135,17 @@ } | ||
/** | ||
* Helper method for initializing a button and linking it with an appropriate command. | ||
* Helper method for initializing the button and linking it with an appropriate command. | ||
* | ||
* @private | ||
* @param {String} style The name of style for which add button. | ||
* @param {String} option The name of the alignment option for which the button is added. | ||
*/ | ||
_addButton( style ) { | ||
_addButton( option ) { | ||
const editor = this.editor; | ||
const commandName = AlignmentEditing.commandName( style ); | ||
const command = editor.commands.get( commandName ); | ||
editor.ui.componentFactory.add( commandName, locale => { | ||
editor.ui.componentFactory.add( `alignment:${ option }`, locale => { | ||
const command = editor.commands.get( 'alignment' ); | ||
const buttonView = new ButtonView( locale ); | ||
buttonView.set( { | ||
label: this.localizedStylesTitles[ style ], | ||
icon: icons.get( style ), | ||
label: this.localizedOptionTitles[ option ], | ||
icon: icons.get( option ), | ||
tooltip: true | ||
@@ -140,7 +155,8 @@ } ); | ||
// Bind button model to command. | ||
buttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); | ||
buttonView.bind( 'isEnabled' ).to( command ); | ||
buttonView.bind( 'isOn' ).to( command, 'value', value => value === option ); | ||
// Execute command. | ||
this.listenTo( buttonView, 'execute', () => { | ||
editor.execute( commandName ); | ||
editor.execute( 'alignment', { value: option } ); | ||
editor.editing.view.focus(); | ||
@@ -147,0 +163,0 @@ } ); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 3 instances in 1 package
28283
24
0
22
14
400
1
+ Added@ckeditor/ckeditor5-core@1.0.0-beta.4(transitive)
+ Added@ckeditor/ckeditor5-engine@1.0.0-beta.4(transitive)
+ Added@ckeditor/ckeditor5-theme-lark@1.0.0-beta.4(transitive)
+ Added@ckeditor/ckeditor5-ui@1.0.0-beta.4(transitive)
+ Added@ckeditor/ckeditor5-utils@1.0.0-beta.4(transitive)
- Removed@ckeditor/ckeditor5-core@43.3.1(transitive)
- Removed@ckeditor/ckeditor5-engine@43.3.1(transitive)
- Removed@ckeditor/ckeditor5-ui@43.3.1(transitive)
- Removed@ckeditor/ckeditor5-utils@43.3.1(transitive)
- Removed@ckeditor/ckeditor5-watchdog@43.3.1(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedcolor-parse@1.4.2(transitive)
- Removedlodash-es@4.17.21(transitive)
- Removedvanilla-colorful@0.7.2(transitive)