Skip to content

Commit

Permalink
Merge branch 't/10856' into major
Browse files Browse the repository at this point in the history
  • Loading branch information
mlewand committed Oct 25, 2013
2 parents b6d7b38 + 9a0b6d8 commit 2c90b87
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -5,6 +5,7 @@ CKEditor 4 Changelog

New Features:

* [#10856](http://dev.ckeditor.com/ticket/10856): Menu-buttons will now toggle their panels visibility when clicked multiple times. Language plugin fixes: added active language highlighting, added option to remove language.
* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.
* [#10855](http://dev.ckeditor.com/ticket/10855): Change extension of emotes in BBCode sample from GIF to PNG.
* [#11002](http://dev.ckeditor.com/ticket/11002): Added option to disable widgets drag and drop support.
Expand Down
3 changes: 2 additions & 1 deletion plugins/language/lang/en.js
Expand Up @@ -4,5 +4,6 @@
*/

CKEDITOR.plugins.setLang( 'language', 'en', {
button: 'Set language'
button: 'Set language',
remove: 'Remove language'
} );
79 changes: 66 additions & 13 deletions plugins/language/plugin.js
Expand Up @@ -22,73 +22,126 @@

init: function( editor ) {
var languagesConfigStrings = ( editor.config.language_list || [ 'ar:Arabic:rtl', 'fr:French', 'es:Spanish' ] ),
plugin = this,
lang = editor.lang.language,
items = {},
parts,
curLanguageId, // 2-letter language identifier.
languageButtonId, // Will store button namespaced identifier, like "language_en".
i;

// Registers command.
editor.addCommand( 'language', {
allowedContent: allowedContent,
requiredContent: requiredContent,
contextSensitive: true,
exec: function( editor, languageId ) {
if ( items[ languageId ] )
editor.applyStyle( items[ languageId ].style );
var item = items[ 'language_' + languageId ];

if ( item )
editor[ item.style.checkActive( editor.elementPath() ) ? 'removeStyle' : 'applyStyle' ]( item.style );
},
refresh: function( editor, path ) {
this.setState( plugin.getCurrentLangElement( editor ) ?
CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
}
} );

// Parse languagesConfigStrings, and create items entry for each lang.
for ( i = 0; i < languagesConfigStrings.length; i++ ) {
parts = languagesConfigStrings[ i ].split( ':' );
curLanguageId = parts[ 0 ];
languageButtonId = 'language_' + curLanguageId;

items[ curLanguageId ] = {
items[ languageButtonId ] = {
label: parts[ 1 ],
langId: curLanguageId,
group: 'language',
order: i,
// Tells if this language is left-to-right oriented (default: true).
ltr: ( '' + parts[ 2 ] ).toLowerCase() != 'rtl',
// Style property will be assigned after object initialization.
style: null,
onClick: function() {
editor.execCommand( 'language', this.langId );
}
};

// Init style property.
items[ curLanguageId ].style = new CKEDITOR.style( {
items[ languageButtonId ].style = new CKEDITOR.style( {
element: 'span',
attributes: {
lang: curLanguageId,
dir: items[ curLanguageId ].ltr ? 'ltr' : 'rtl'
dir: items[ languageButtonId ].ltr ? 'ltr' : 'rtl'
}
} );
}

// Initialize group/button.
// Remove language indicator button.
items.language_remove = {
label: lang.remove,
group: 'language_remove',
state: CKEDITOR.TRISTATE_DISABLED,
order: items.length,
onClick: function() {
var currentLanguagedElement = plugin.getCurrentLangElement( editor );

if ( currentLanguagedElement )
editor.execCommand( 'language', currentLanguagedElement.getAttribute( 'lang' ) );
}
};

// Initialize groups for menu.
editor.addMenuGroup( 'language', 1 );
editor.addMenuGroup( 'language_remove' ); // Group order is skipped intentionally, it will be placed at the end.
editor.addMenuItems( items );

editor.ui.add( 'language', CKEDITOR.UI_MENUBUTTON, {
label: editor.lang.language.button,
label: lang.button,
// MenuButtons do not (yet) has toFeature method, so we cannot do this:
// toFeature: function( editor ) { return editor.getCommand( 'language' ); }
// Set feature's properties directly on button.
allowedContent: allowedContent,
requiredContent: requiredContent,
toolbar: 'bidi,30',
modes: { wysiwyg: 1 },
className: 'cke_button_language',
command: 'language',
onMenu: function() {
var activeItems = {};
var activeItems = {},
currentLanguagedElement = plugin.getCurrentLangElement( editor );

for ( var prop in items )
activeItems[ prop ] = CKEDITOR.TRISTATE_ON;
activeItems[ prop ] = CKEDITOR.TRISTATE_OFF;

activeItems.language_remove = currentLanguagedElement ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;

if ( currentLanguagedElement )
activeItems[ 'language_' + currentLanguagedElement.getAttribute( 'lang' ) ] = CKEDITOR.TRISTATE_ON;

return activeItems;
}
} );
},

/**
* Gets the first language element for the current editor selection.
* @param {CKEDITOR.editor} editor
* @returns {CKEDITOR.dom.element} The language element, if any.
* @member CKEDITOR.plugins.language
*/
getCurrentLangElement: function( editor ) {
var elementPath = editor.elementPath(),
activePath = elementPath && elementPath.elements,
pathMember, ret;

// IE8: upon initialization if there is no path elementPath() returns null.
if ( elementPath ) {
for ( var i = 0; i < activePath.length; i++ ) {
pathMember = activePath[ i ];

if ( !ret && pathMember.getName() == 'span' && pathMember.hasAttribute( 'dir' ) && pathMember.hasAttribute( 'lang' ) )
ret = pathMember;
}
}

return ret;
}
} );
})();
Expand Down
19 changes: 11 additions & 8 deletions plugins/menubutton/plugin.js
Expand Up @@ -7,16 +7,21 @@ CKEDITOR.plugins.add( 'menubutton', {
requires: 'button,menu',
onLoad: function() {
var clickFn = function( editor ) {
var _ = this._;
var _ = this._,
menu = _.menu;

// Do nothing if this button is disabled.
if ( _.state === CKEDITOR.TRISTATE_DISABLED )
return;

if ( _.on && menu ) {
menu.hide();
return;
}

_.previousState = _.state;

// Check if we already have a menu for it, otherwise just create it.
var menu = _.menu;
if ( !menu ) {
menu = _.menu = new CKEDITOR.menu( editor, {
panel: {
Expand All @@ -26,20 +31,18 @@ CKEDITOR.plugins.add( 'menubutton', {
});

menu.onHide = CKEDITOR.tools.bind( function() {
this.setState( this.modes && this.modes[ editor.mode ] ? _.previousState : CKEDITOR.TRISTATE_DISABLED );
var modes = this.command ? editor.getCommand( this.command ).modes : this.modes;
this.setState( !modes || modes[ editor.mode ] ? _.previousState : CKEDITOR.TRISTATE_DISABLED );
_.on = 0;
}, this );

// Initialize the menu items at this point.
if ( this.onMenu )
menu.addListener( this.onMenu );
}

if ( _.on ) {
menu.hide();
return;
}

this.setState( CKEDITOR.TRISTATE_ON );
_.on = 1;

// This timeout is needed to give time for the panel get focus
// when JAWS is running. (#9842)
Expand Down
19 changes: 19 additions & 0 deletions skins/kama/menu.css
Expand Up @@ -134,13 +134,32 @@ Special outer level classes used in this file:
filter: alpha(opacity=30);
}

.cke_menubutton_on
{
border: 1px solid #ccc;
background-color: #e9f5ff;
}

.cke_menubutton_on .cke_menubutton_icon
{
padding-right: 3px;
}

.cke_menubutton:hover,
.cke_menubutton:focus,
.cke_menubutton:active
{
background-color: #D3D3D3;
}

.cke_menubutton_on:hover,
.cke_menubutton_on:focus,
.cke_menubutton_on:active
{
border-color: #316ac5;
background-color: #dff1ff;
}

.cke_panel_frame .cke_menubutton_label
{
display: none;
Expand Down
15 changes: 15 additions & 0 deletions skins/moono/menu.css
Expand Up @@ -140,6 +140,21 @@ Special outer level classes used in this file:
filter: alpha(opacity=30);
}

.cke_menubutton_on
{
border: 1px solid #dedede;
background-color: #f2f2f2;

-moz-box-shadow: 0 0 2px rgba(0,0,0,.1) inset;
-webkit-box-shadow: 0 0 2px rgba(0,0,0,.1) inset;
box-shadow: 0 0 2px rgba(0,0,0,.1) inset;
}

.cke_menubutton_on .cke_menubutton_icon
{
padding-right: 3px;
}

.cke_menubutton:hover,
.cke_menubutton:focus,
.cke_menubutton:active
Expand Down

0 comments on commit 2c90b87

Please sign in to comment.