Index: /CKEditor/branches/versions/3.5.x/CHANGES.html =================================================================== --- /CKEditor/branches/versions/3.5.x/CHANGES.html (revision 6127) +++ /CKEditor/branches/versions/3.5.x/CHANGES.html (revision 6128) @@ -45,4 +45,5 @@
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js =================================================================== --- /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js (revision 6127) +++ /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js (revision 6128) @@ -127,8 +127,16 @@ colorStyle.childRule = type == 'back' ? - // It's better to apply background color as the innermost style. (#3599) - function(){ return false; } : - // Fore color style must be applied inside links instead of around it. - function( element ){ return element.getName() != 'a'; }; + function( element ) + { + // It's better to apply background color as the innermost style. (#3599) + // Except for "unstylable elements". (#6103) + return isUnstylable( element ); + } + : + function( element ) + { + // Fore color style must be applied inside links instead of around it. + return element.getName() != 'a' || isUnstylable( element ); + }; new CKEDITOR.style( colorStyle, { color : color } ).apply( editor.document ); @@ -208,4 +216,9 @@ return output.join( '' ); } + + function isUnstylable( ele ) + { + return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-cke-nostyle' ); + } } }); Index: /CKEditor/branches/versions/3.5.x/_source/plugins/styles/plugin.js =================================================================== --- /CKEditor/branches/versions/3.5.x/_source/plugins/styles/plugin.js (revision 6127) +++ /CKEditor/branches/versions/3.5.x/_source/plugins/styles/plugin.js (revision 6128) @@ -6,5 +6,15 @@ CKEDITOR.plugins.add( 'styles', { - requires : [ 'selection' ] + requires : [ 'selection' ], + init : function( editor ) + { + // This doesn't look like correct, but it's the safest way to proper + // pass the disableReadonlyStyling configuration to the style system + // without having to change any method signature in the API. (#6103) + editor.on( 'contentDom', function() + { + editor.document.setCustomData( 'cke_includeReadonly', !editor.config.disableReadonlyStyling ); + }); + } }); @@ -354,4 +364,33 @@ }; + // Gets the parent element which blocks the styling for an element. This + // can be done through read-only elements (contenteditable=false) or + // elements with the "data-cke-nostyle" attribute. + function getUnstylableParent( element ) + { + var unstylable, + editable; + + while ( ( element = element.getParent() ) ) + { + if ( element.getName() == 'body' ) + break; + + if ( element.getAttribute( 'data-cke-nostyle' ) ) + unstylable = element; + else if ( !editable ) + { + var contentEditable = element.getAttribute( 'contentEditable' ); + + if ( contentEditable == 'false' ) + unstylable = element; + else if ( contentEditable == 'true' ) + editable = 1; + } + } + + return unstylable; + } + function applyInlineStyle( range ) { @@ -375,4 +414,12 @@ var def = this._.definition; var isUnknownElement; + + // Indicates that fully selected read-only elements are to be included in the styling range. + var includeReadonly = def.includeReadonly; + + // If the read-only inclusion is not available in the definition, try + // to get it from the document data. + if ( includeReadonly == undefined ) + includeReadonly = document.getCustomData( 'cke_includeReadonly' ); // Get the DTD definition for the element. Defaults to "span". @@ -393,4 +440,22 @@ var styleRange; + // Check if the boundaries are inside non stylable elements. + var firstUnstylable = getUnstylableParent( firstNode ), + lastUnstylable = getUnstylableParent( lastNode ); + + // If the first element can't be styled, we'll start processing right + // after its unstylable root. + if ( firstUnstylable ) + currentNode = firstUnstylable.getNextSourceNode( true ); + + // If the last element can't be styled, we'll stop processing on its + // unstylable root. + if ( lastUnstylable ) + lastNode = lastUnstylable; + + // Do nothing if the current node now follows the last node to be processed. + if ( currentNode.getPosition( lastNode ) == CKEDITOR.POSITION_FOLLOWING ) + currentNode = 0; + while ( currentNode ) { @@ -406,4 +471,6 @@ var nodeType = currentNode.type; var nodeName = nodeType == CKEDITOR.NODE_ELEMENT ? currentNode.getName() : null; + var nodeIsReadonly = nodeName && ( currentNode.getAttribute( 'contentEditable' ) == 'false' ); + var nodeIsNoStyle = nodeName && currentNode.getAttribute( 'data-cke-nostyle' ); if ( nodeName && currentNode.data( 'cke-bookmark' ) ) @@ -415,4 +482,6 @@ // Check if the current node can be a child of the style element. if ( !nodeName || ( dtd[ nodeName ] + && !nodeIsNoStyle + && ( !nodeIsReadonly || includeReadonly ) && ( currentNode.getPosition( lastNode ) | CKEDITOR.POSITION_PRECEDING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED ) == ( CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_IDENTICAL + CKEDITOR.POSITION_IS_CONTAINED ) && ( !def.childRule || def.childRule( currentNode ) ) ) ) @@ -436,7 +505,7 @@ } - // Non element nodes, or empty elements can be added - // completely to the range. - if ( nodeType == CKEDITOR.NODE_TEXT || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() ) ) + // Non element nodes, readonly elements, or empty + // elements can be added completely to the range. + if ( nodeType == CKEDITOR.NODE_TEXT || nodeIsReadonly || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() ) ) { var includedNode = currentNode; @@ -462,5 +531,4 @@ if ( !includedNode.$.nextSibling ) applyStyle = true; - } } @@ -472,5 +540,5 @@ // Get the next node to be processed. - currentNode = currentNode.getNextSourceNode(); + currentNode = currentNode.getNextSourceNode( nodeIsNoStyle || nodeIsReadonly ); } @@ -1356,5 +1424,5 @@ // Bookmark the range so we can re-select it after processing. bookmarks = selection.createBookmarks( 1 ), - ranges = selection.getRanges( 1 ), + ranges = selection.getRanges(), func = remove ? this.removeFromRange : this.applyToRange, range; @@ -1448,4 +1516,21 @@ callback( this._.stylesDefinitions ); }; + +/** + * Indicates that fully selected read-only elements will be included when + * applying the style (for inline styles only). + * @name CKEDITOR.style.includeReadonly + * @type Boolean + * @default false + * @since 3.5 + */ + + /** + * Disables inline styling on read-only elements. + * @name CKEDITOR.config.disableReadonlyStyling + * @type Boolean + * @default false + * @since 3.5 + */ /**