Skip to content

Commit

Permalink
Merge pull request #1531 from ckeditor/t/1530
Browse files Browse the repository at this point in the history
Added possibility to use custom icons in buttons
  • Loading branch information
Comandeer authored Feb 6, 2018
2 parents 2d63a79 + 0fbe103 commit 1bd76f3
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Fixed Issues:
API Changes:

* [#1346](https://github.com/ckeditor/ckeditor-dev/issues/1346): [Balloon Toolbar](https://ckeditor.com/cke4/addon/balloontoolbar) [context manager API](https://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR.plugins.balloontoolbar.contextManager) is now available in [pluginDefinition.init](https://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR.pluginDefinition-method-init) method of a [requiring](https://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR.pluginDefinition-property-requires) plugin.
* [#1530](https://github.com/ckeditor/ckeditor-dev/issues/1530): Added possibility to use custom icons for [buttons](CKEDITOR.ui.button).

Other Changes:

Expand Down
56 changes: 53 additions & 3 deletions plugins/button/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
btnTpl = CKEDITOR.addTemplate( 'button', template );

CKEDITOR.plugins.add( 'button', {
// jscs:disable maximumLineLength
lang: 'af,ar,az,bg,ca,cs,da,de,de-ch,el,en,en-au,en-gb,eo,es,es-mx,eu,fa,fi,fr,gl,he,hr,hu,id,it,ja,km,ko,ku,lt,nb,nl,no,oc,pl,pt,pt-br,ro,ru,sk,sl,sq,sv,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
// jscs:enable maximumLineLength
beforeInit: function( editor ) {
editor.ui.addHandler( CKEDITOR.UI_BUTTON, CKEDITOR.ui.button.handler );
}
Expand Down Expand Up @@ -117,6 +119,8 @@
* this button should be appended.
*/
render: function( editor, output ) {
var modeStates = null;

function updateState() {
// "this" is a CKEDITOR.ui.button instance.
var mode = editor.mode;
Expand Down Expand Up @@ -198,7 +202,7 @@

// Indicate a mode sensitive button.
if ( this.modes ) {
var modeStates = {};
modeStates = {};

editor.on( 'beforeModeUnload', function() {
if ( editor.mode && this._.state != CKEDITOR.TRISTATE_DISABLED )
Expand All @@ -224,6 +228,8 @@
}
}

var iconName;

// For button that has text-direction awareness on selection path.
if ( this.directional ) {
editor.on( 'contentDirChanged', function( evt ) {
Expand Down Expand Up @@ -254,12 +260,30 @@
}

var name = this.name || this.command,
iconName = name;
iconPath = null;

iconName = name;

// Check if we're pointing to an icon defined by another command. (https://dev.ckeditor.com/ticket/9555)
if ( this.icon && !( /\./ ).test( this.icon ) ) {
iconName = this.icon;
this.icon = null;

} else {
// Register and use custom icon for button (#1530).
if ( this.icon ) {
iconPath = this.icon;
}
if ( CKEDITOR.env.hidpi && this.iconHiDpi ) {
iconPath = this.iconHiDpi;
}
}

if ( iconPath ) {
CKEDITOR.skin.addIcon( iconPath, iconPath );
this.icon = null;
} else {
iconPath = iconName;
}

var params = {
Expand All @@ -277,7 +301,7 @@
keydownFn: keydownFn,
focusFn: focusFn,
clickFn: clickFn,
style: CKEDITOR.skin.getIconStyle( iconName, ( editor.lang.dir == 'rtl' ), this.icon, this.iconOffset ),
style: CKEDITOR.skin.getIconStyle( iconPath, ( editor.lang.dir == 'rtl' ), this.icon, this.iconOffset ),
arrowHtml: this.hasArrow ? btnArrowTpl.output() : ''
};

Expand Down Expand Up @@ -381,6 +405,32 @@
* @param {String} definition.command The command to be executed once the button is activated.
* @param {String} definition.toolbar The {@link CKEDITOR.config#toolbarGroups toolbar group} into which
* the button will be added. An optional index value (separated by a comma) determines the button position within the group.
* @param {String} definition.icon Path to custom icon or icon name registered by another plugin. Custom icon paths
* are supported since **4.9.0** version.
*
* To use icon registered by another plugin, icon parameter should be used like:
*
* editor.ui.addButton( 'my_button', {
* icon: 'Link' // Uses link icon from Link plugin.
* } );
*
* If the plugin provides HiDPI version of an icon it will be used for HiDPI displays (so defining `iconHiDpi` is not needed
* in this case).
*
* To use custom icon, path to icon should be provided like:
*
* editor.ui.addButton( 'my_button', {
* icon: 'assets/icons/my_button.png'
* } )
*
* This icon will be used for both standard and HiDPI displays unless `iconHiDpi` is explicitly defined.
* **Important**: CKEditor will resolve relative paths based on {@link CKEDITOR#basePath}.
* @param {String} definition.iconHiDpi Path to custom HiDPI icon version. Supported since **4.9.0** version.
* It will be used only in HiDPI environments. Usage is similar to `icon` parameter:
*
* editor.ui.addButton( 'my_button', {
* iconHiDpi: 'assets/icons/my_button.hidpi.png'
* } )
*/
CKEDITOR.ui.prototype.addButton = function( name, definition ) {
this.add( name, CKEDITOR.UI_BUTTON, definition );
Expand Down
Binary file added tests/_assets/sample_icon.hidpi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/_assets/sample_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
264 changes: 264 additions & 0 deletions tests/plugins/button/buttonicon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/* bender-tags: editor */
/* bender-ckeditor-plugins: button,toolbar */

( function() {
'use strict';

var editorCounter = 0,
originalBasePath = null,
isDev = CKEDITOR.version === '%VERSION%',
isHidpi,
tests;

function createIconTests( testsObj, tests ) {
CKEDITOR.tools.array.forEach( tests, function( test ) {
testsObj[ test.name ] = function() {
if ( test.ignore ) {
// On a build version icons sprite image is loaded before any test code is execute so we are not able
// to emulate `CKEDITOR.env.hidpi` to force different icons loading. Due to this behaviour some tests
// needs to be ignored in build version.
assert.ignore();
} else {
CKEDITOR.env.hidpi = test.name.indexOf( 'hidpi' ) !== -1;
assertIcon( test.config, test.button, test.iconPath, test.iconName );
}
};
} );
}

function assertIcon( editorConfig, btnName, iconPath, iconName ) {
editorCounter++;
bender.editorBot.create( {
name: 'editor' + editorCounter,
config: editorConfig
}, function( bot ) {
var btn = bot.editor.ui.get( btnName ),
btnEl = CKEDITOR.document.getById( btn._.id ),
btnCss = CKEDITOR.tools.parseCssText( btnEl.findOne( '.cke_button_icon' ).getAttribute( 'style' ), true );

if ( iconPath === undefined ) {
// Standard icon should be checked.
if ( isDev ) {
var iconFileName = ( iconName || btnName ).toLowerCase(),
hidpi = CKEDITOR.env.hidpi ? 'hidpi\\/' : '';

iconPath = new RegExp( 'plugins\\/' + iconFileName + '\\/icons\\/' + hidpi + iconFileName + '\\.png', 'gi' );
} else {
// In build version all standard icons are inside 'icons.png' sprite.
iconPath = CKEDITOR.env.hidpi ? /plugins\/icons_hidpi\.png/gi : /plugins\/icons\.png/gi;
}
}

assert.isMatching( iconPath, btnCss[ 'background-image' ] );
} );
}

tests = {
init: function() {
isHidpi = CKEDITOR.env.hidpi;
},

tearDown: function() {
// Restore global values modified by tests.
CKEDITOR.env.hidpi = isHidpi;
if ( originalBasePath ) {
CKEDITOR.basePath = originalBasePath;
originalBasePath = null;
}
}
};

createIconTests( tests, [
{
name: 'test default button icon',
button: 'Link',
config: {
extraPlugins: 'link'
},
ignore: !isDev && CKEDITOR.env.hidpi
}, {
name: 'test default button icon (hidpi)',
button: 'Find',
config: {
extraPlugins: 'find'
},
ignore: !isDev && !CKEDITOR.env.hidpi
}, {
name: 'test overwriting default button icon',
button: 'Replace',
iconPath: /tests\/_assets\/sample_icon\.png/gi,
config: {
extraPlugins: 'find',
toolbar: [ [ 'Replace' ] ],
on: {
pluginsLoaded: function( evt ) {
var editor = evt.editor;
editor.ui.addButton( 'Replace', {
label: editor.lang.find.replace,
command: 'replace',
icon: 'tests/_assets/sample_icon.png'
} );
}
}
}
}, {
name: 'test overwriting default button icon (hidpi)',
button: 'Replace',
iconPath: /tests\/_assets\/sample_icon\.hidpi\.png/gi,
config: {
extraPlugins: 'find',
toolbar: [ [ 'Replace' ] ],
on: {
pluginsLoaded: function( evt ) {
var editor = evt.editor;
editor.ui.addButton( 'Replace', {
label: editor.lang.find.replace,
command: 'replace',
iconHiDpi: 'tests/_assets/sample_icon.hidpi.png'
} );
}
}
}
}, {
name: 'test button icon from different plugin',
button: 'custom_btn1',
iconName: 'about',
config: {
extraPlugins: 'about',
toolbar: [ [ 'custom_btn1' ] ],
on: {
pluginsLoaded: function( evt ) {
evt.editor.ui.addButton( 'custom_btn1', {
icon: 'about'
} );
}
}
},
ignore: !isDev && CKEDITOR.env.hidpi
}, {
name: 'test button icon from different plugin (hidpi)',
button: 'custom_btn2',
iconName: 'blockquote',
config: {
extraPlugins: 'blockquote',
toolbar: [ [ 'custom_btn2' ] ],
on: {
pluginsLoaded: function( evt ) {
evt.editor.ui.addButton( 'custom_btn2', {
icon: 'blockquote'
} );
}
}
},
ignore: !isDev && !CKEDITOR.env.hidpi
}, {
name: 'test custom button icon',
button: 'custom_btn3',
iconPath: /tests\/_assets\/sample_icon\.png/gi,
config: {
toolbar: [ [ 'custom_btn3' ] ],
on: {
pluginsLoaded: function( evt ) {
evt.editor.ui.addButton( 'custom_btn3', {
icon: 'tests/_assets/sample_icon.png'
} );
}
}
}
}, {
name: 'test custom button icon (hidpi)',
button: 'custom_btn4',
iconPath: /tests\/_assets\/sample_icon\.hidpi\.png/gi,
config: {
toolbar: [ [ 'custom_btn4' ] ],
on: {
pluginsLoaded: function( evt ) {
evt.editor.ui.addButton( 'custom_btn4', {
iconHiDpi: 'tests/_assets/sample_icon.hidpi.png'
} );
}
}
}
}, {
name: 'test custom button icon-only (hidpi)',
button: 'custom_btn5',
iconPath: /tests\/_assets\/sample_icon\.png/gi,
config: {
toolbar: [ [ 'custom_btn5' ] ],
on: {
pluginsLoaded: function( evt ) {
evt.editor.ui.addButton( 'custom_btn5', {
icon: 'tests/_assets/sample_icon.png'
} );
}
}
}
}, {
name: 'test custom button icon with different basepath',
button: 'custom_btn6',
iconPath: /different\/basepath\/assets\/icons\.sample\.png/gi,
config: {
toolbar: [ [ 'custom_btn6' ] ],
on: {
pluginsLoaded: function( evt ) {
originalBasePath = CKEDITOR.basePath;
CKEDITOR.basePath = '/different/basepath/';
evt.editor.ui.addButton( 'custom_btn6', {
icon: 'assets/icons.sample.png'
} );
}
}
}
}, {
name: 'test custom button icon with different basepath (hidpi)',
button: 'custom_btn7',
iconPath: /different\/basepath\/assets\/hidpi\/icons\.sample\.png/gi,
config: {
toolbar: [ [ 'custom_btn7' ] ],
on: {
pluginsLoaded: function( evt ) {
originalBasePath = CKEDITOR.basePath;
CKEDITOR.basePath = '/different/basepath/';
evt.editor.ui.addButton( 'custom_btn7', {
icon: 'assets/hidpi/icons.sample.png'
} );
}
}
}
}, {
name: 'test custom button icon with different basepath trailing slash',
button: 'custom_btn8',
iconPath: /['|(]\/assets\/icons\.sample\.png/gi,
config: {
toolbar: [ [ 'custom_btn8' ] ],
on: {
pluginsLoaded: function( evt ) {
originalBasePath = CKEDITOR.basePath;
CKEDITOR.basePath = '/different/basepath/';
evt.editor.ui.addButton( 'custom_btn8', {
icon: '/assets/icons.sample.png'
} );
}
}
}
}, {
name: 'test custom button icon with different basepath trailing slash (hidpi)',
button: 'custom_btn9',
iconPath: /['|(]\/assets\/hidpi\/icons\.sample\.png/gi,
config: {
toolbar: [ [ 'custom_btn9' ] ],
on: {
pluginsLoaded: function( evt ) {
originalBasePath = CKEDITOR.basePath;
CKEDITOR.basePath = '/different/basepath/';
evt.editor.ui.addButton( 'custom_btn9', {
icon: '/assets/hidpi/icons.sample.png'
} );
}
}
}
}
] );

bender.test( tests );
} )();
Loading

0 comments on commit 1bd76f3

Please sign in to comment.