Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #96 from ckeditor/t/ckeditor5/488
Browse files Browse the repository at this point in the history
Other: Align feature class naming to a new scheme.
  • Loading branch information
scofalik authored Feb 27, 2018
2 parents 263707b + 2843d17 commit 511a9d8
Show file tree
Hide file tree
Showing 7 changed files with 424 additions and 391 deletions.
125 changes: 10 additions & 115 deletions src/heading.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,17 @@
* @module heading/heading
*/

import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import HeadingEngine from './headingengine';
import HeadingEditing from './headingediting';
import HeadingUI from './headingui';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import Model from '@ckeditor/ckeditor5-ui/src/model';

import { createDropdown, addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';

import Collection from '@ckeditor/ckeditor5-utils/src/collection';

import '../theme/heading.css';

/**
* The headings feature. It introduces the `headings` drop-down and the `heading1`-`headingN` commands which allow
* to convert paragraphs into headings.
* The headings feature.
*
* It loads the {@link module:heading/headingediting~HeadingEditing heading editing feature}
* and {@link module:heading/headingui~HeadingUI heading UI feature}.
*
* For a detailed overview, check the {@glink features/headings Headings feature documentation}.
*
Expand All @@ -31,7 +28,7 @@ export default class Heading extends Plugin {
* @inheritDoc
*/
static get requires() {
return [ Paragraph, HeadingEngine ];
return [ HeadingEditing, HeadingUI ];
}

/**
Expand All @@ -40,112 +37,10 @@ export default class Heading extends Plugin {
static get pluginName() {
return 'Heading';
}

/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const t = editor.t;
const options = this._getLocalizedOptions();
const defaultTitle = t( 'Choose heading' );
const dropdownTooltip = t( 'Heading' );

// Register UI component.
editor.ui.componentFactory.add( 'headings', locale => {
const commands = [];
const dropdownItems = new Collection();

for ( const option of options ) {
const command = editor.commands.get( option.model );
const itemModel = new Model( {
commandName: option.model,
label: option.title,
class: option.class
} );

itemModel.bind( 'isActive' ).to( command, 'value' );

// Add the option to the collection.
dropdownItems.add( itemModel );

commands.push( command );
}

const dropdownView = createDropdown( locale );
addListToDropdown( dropdownView, dropdownItems );

dropdownView.buttonView.set( {
isOn: false,
withText: true,
tooltip: dropdownTooltip
} );

dropdownView.extendTemplate( {
attributes: {
class: [
'ck-heading-dropdown'
]
}
} );

dropdownView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {
return areEnabled.some( isEnabled => isEnabled );
} );

dropdownView.buttonView.bind( 'label' ).toMany( commands, 'value', ( ...areActive ) => {
const index = areActive.findIndex( value => value );

// If none of the commands is active, display default title.
return options[ index ] ? options[ index ].title : defaultTitle;
} );

// Execute command when an item from the dropdown is selected.
this.listenTo( dropdownView, 'execute', evt => {
editor.execute( evt.source.commandName );
editor.editing.view.focus();
} );

return dropdownView;
} );
}

/**
* Returns heading options as defined in `config.heading.options` but processed to consider
* editor localization, i.e. to display {@link module:heading/heading~HeadingOption}
* in the correct language.
*
* Note: The reason behind this method is that there's no way to use {@link module:utils/locale~Locale#t}
* when the user config is defined because the editor does not exist yet.
*
* @private
* @returns {Array.<module:heading/heading~HeadingOption>}.
*/
_getLocalizedOptions() {
const editor = this.editor;
const t = editor.t;
const localizedTitles = {
Paragraph: t( 'Paragraph' ),
'Heading 1': t( 'Heading 1' ),
'Heading 2': t( 'Heading 2' ),
'Heading 3': t( 'Heading 3' )
};

return editor.config.get( 'heading.options' ).map( option => {
const title = localizedTitles[ option.title ];

if ( title && title != option.title ) {
// Clone the option to avoid altering the original `config.heading.options`.
option = Object.assign( {}, option, { title } );
}

return option;
} );
}
}

/**
* The configuration of the heading feature. Introduced by the {@link module:heading/headingengine~HeadingEngine} feature.
* The configuration of the heading feature. Introduced by the {@link module:heading/headingediting~HeadingEditing} feature.
*
* Read more in {@link module:heading/heading~HeadingConfig}.
*
Expand All @@ -154,7 +49,7 @@ export default class Heading extends Plugin {

/**
* The configuration of the heading feature.
* The option is used by the {@link module:heading/headingengine~HeadingEngine} feature.
* The option is used by the {@link module:heading/headingediting~HeadingEditing} feature.
*
* ClassicEditor
* .create( {
Expand Down Expand Up @@ -191,7 +86,7 @@ export default class Heading extends Plugin {
* Usually, the first option in the headings dropdown is the "Paragraph" option, hence it's also defined on the list.
* However, you don't need to define its view representation because it's handled by
* the {@link module:paragraph/paragraph~Paragraph} feature (which is required by
* the {@link module:heading/headingengine~HeadingEngine} feature).
* the {@link module:heading/headingediting~HeadingEditing} feature).
*
* You can **read more** about configuring heading levels and **see more examples** in
* the {@glink features/headings Headings} guide.
Expand Down
5 changes: 3 additions & 2 deletions src/headingengine.js → src/headingediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

/**
* @module heading/headingengine
* @module heading/headingediting
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
Expand All @@ -16,10 +16,11 @@ const defaultModelElement = 'paragraph';
/**
* The headings engine feature. It handles switching between block formats &ndash; headings and paragraph.
* This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.
* It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.
*
* @extends module:core/plugin~Plugin
*/
export default class HeadingEngine extends Plugin {
export default class HeadingEditing extends Plugin {
/**
* @inheritDoc
*/
Expand Down
126 changes: 126 additions & 0 deletions src/headingui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/**
* @module heading/headingui
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import Model from '@ckeditor/ckeditor5-ui/src/model';

import { createDropdown, addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';

import Collection from '@ckeditor/ckeditor5-utils/src/collection';

import '../theme/heading.css';

/**
* The headings UI feature. It introduces the `headings` drop-down.
*
* @extends module:core/plugin~Plugin
*/
export default class HeadingUI extends Plugin {
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const t = editor.t;
const options = this._getLocalizedOptions();
const defaultTitle = t( 'Choose heading' );
const dropdownTooltip = t( 'Heading' );

// Register UI component.
editor.ui.componentFactory.add( 'headings', locale => {
const commands = [];
const dropdownItems = new Collection();

for ( const option of options ) {
const command = editor.commands.get( option.model );
const itemModel = new Model( {
commandName: option.model,
label: option.title,
class: option.class
} );

itemModel.bind( 'isActive' ).to( command, 'value' );

// Add the option to the collection.
dropdownItems.add( itemModel );

commands.push( command );
}

const dropdownView = createDropdown( locale );
addListToDropdown( dropdownView, dropdownItems );

dropdownView.buttonView.set( {
isOn: false,
withText: true,
tooltip: dropdownTooltip
} );

dropdownView.extendTemplate( {
attributes: {
class: [
'ck-heading-dropdown'
]
}
} );

dropdownView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {
return areEnabled.some( isEnabled => isEnabled );
} );

dropdownView.buttonView.bind( 'label' ).toMany( commands, 'value', ( ...areActive ) => {
const index = areActive.findIndex( value => value );

// If none of the commands is active, display default title.
return options[ index ] ? options[ index ].title : defaultTitle;
} );

// Execute command when an item from the dropdown is selected.
this.listenTo( dropdownView, 'execute', evt => {
editor.execute( evt.source.commandName );
editor.editing.view.focus();
} );

return dropdownView;
} );
}

/**
* Returns heading options as defined in `config.heading.options` but processed to consider
* editor localization, i.e. to display {@link module:heading/heading~HeadingOption}
* in the correct language.
*
* Note: The reason behind this method is that there's no way to use {@link module:utils/locale~Locale#t}
* when the user config is defined because the editor does not exist yet.
*
* @private
* @returns {Array.<module:heading/heading~HeadingOption>}.
*/
_getLocalizedOptions() {
const editor = this.editor;
const t = editor.t;
const localizedTitles = {
Paragraph: t( 'Paragraph' ),
'Heading 1': t( 'Heading 1' ),
'Heading 2': t( 'Heading 2' ),
'Heading 3': t( 'Heading 3' )
};

return editor.config.get( 'heading.options' ).map( option => {
const title = localizedTitles[ option.title ];

if ( title && title != option.title ) {
// Clone the option to avoid altering the original `config.heading.options`.
option = Object.assign( {}, option, { title } );
}

return option;
} );
}
}
Loading

0 comments on commit 511a9d8

Please sign in to comment.