Skip to content

Commit

Permalink
Merge pull request #14413 from ckeditor/ck/13341
Browse files Browse the repository at this point in the history
Fix (style): Styles dropdown should allow styling `<div>` elements. Closes #13341.
  • Loading branch information
arkflpc committed Jun 20, 2023
2 parents 402e866 + 8165c8c commit 4b44f58
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/ckeditor5-html-support/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

export { default as GeneralHtmlSupport } from './generalhtmlsupport';
export { default as DataFilter } from './datafilter';
export { default as DataSchema } from './dataschema';
export { default as DataSchema, type DataSchemaBlockElementDefinition } from './dataschema';
export { default as HtmlComment } from './htmlcomment';
export { default as FullPage } from './fullpage';
export { default as HtmlPageDataProcessor } from './htmlpagedataprocessor';
Expand Down
8 changes: 7 additions & 1 deletion packages/ckeditor5-style/src/styleutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { Element, MatcherPattern, DocumentSelection, Selectable } from 'cke
import type { DecoratedMethodEvent } from 'ckeditor5/src/utils';
import type { TemplateDefinition } from 'ckeditor5/src/ui';

import type { DataFilter, DataSchema, GeneralHtmlSupport } from '@ckeditor/ckeditor5-html-support';
import type { DataFilter, DataSchema, GeneralHtmlSupport, DataSchemaBlockElementDefinition } from '@ckeditor/ckeditor5-html-support';

import type { StyleDefinition } from './styleconfig';
import { isObject } from 'lodash-es';
Expand Down Expand Up @@ -99,7 +99,13 @@ export default class StyleUtils extends Plugin {
if ( typeof appliesToBlock == 'string' ) {
modelElements.push( appliesToBlock );
} else if ( ghsDefinition.isBlock ) {
const ghsBlockDefinition: DataSchemaBlockElementDefinition = ghsDefinition;

modelElements.push( ghsDefinition.model );

if ( ghsBlockDefinition.paragraphLikeModel ) {
modelElements.push( ghsBlockDefinition.paragraphLikeModel );
}
}
} else {
ghsAttributes.push( ghsDefinition.model );
Expand Down
23 changes: 23 additions & 0 deletions packages/ckeditor5-style/tests/manual/styledropdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@
border: 1px solid hsl(120, 89%, 27%);
}

.ck.ck-content div.callout {
background: yellow;
border: 1px solid orange;
padding: 1em;
margin-top: 1em;
margin-bottom: 1em;
}
.ck.ck-content div.callout p:first-child {
margin-top: 0;
}
.ck.ck-content div.callout p:last-child {
margin-bottom: 0;
}

/* ---------------- Inline --------------- */

.ck.ck-content .marker {
Expand Down Expand Up @@ -292,6 +306,15 @@ <h4>Florence, Italy</h4>
</li>
</ol>

<div class="callout">
Div block styled (div as a paragraph).
</div>
<div class="callout">
<p>
Div container styled.
</p>
</div>

</div>

<h2>Just a few inline styles</h2>
Expand Down
5 changes: 5 additions & 0 deletions packages/ckeditor5-style/tests/manual/styledropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ ClassicEditor
...config,
style: {
definitions: [
{
name: 'Callout',
element: 'div',
classes: [ 'callout' ]
},
{
name: 'Link',
element: 'a',
Expand Down
112 changes: 111 additions & 1 deletion packages/ckeditor5-style/tests/stylecommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,23 @@ describe( 'StyleCommand', () => {
}
];

const blockDivStyles = [
{
name: 'Div style',
element: 'div',
classes: [ 'callout' ]
}
];

beforeEach( async () => {
await createEditor( [
...inlineStyles,
...blockParagraphStyles,
...blockHeadingStyles,
...blockCodeBlockStyles,
...blockQuoteBlockStyles,
...blockWidgetStyles
...blockWidgetStyles,
...blockDivStyles
] );
} );

Expand Down Expand Up @@ -174,6 +183,39 @@ describe( 'StyleCommand', () => {
] );
} );

it( 'should enable styles for div (as container)', () => {
setData( model,
'<paragraph>foo</paragraph>' +
'<htmlDiv>' +
'<paragraph>bar[]</paragraph>' +
'</htmlDiv>' +
'<paragraph>baz</paragraph>'
);

command.refresh();

expect( command.enabledStyles ).to.have.members( [
...inlineStyles.map( ( { name } ) => name ),
...blockParagraphStyles.map( ( { name } ) => name ),
...blockDivStyles.map( ( { name } ) => name )
] );
} );

it( 'should enable styles for div (as block)', () => {
setData( model,
'<paragraph>foo</paragraph>' +
'<htmlDivParagraph>bar[]</htmlDivParagraph>' +
'<paragraph>baz</paragraph>'
);

command.refresh();

expect( command.enabledStyles ).to.have.members( [
...inlineStyles.map( ( { name } ) => name ),
...blockDivStyles.map( ( { name } ) => name )
] );
} );

it( 'should enable styles for paragraphs when nested inside html section', () => {
const dataFilter = editor.plugins.get( 'DataFilter' );
dataFilter.allowElement( 'htmlSection' );
Expand Down Expand Up @@ -420,6 +462,32 @@ describe( 'StyleCommand', () => {
expect( command.value ).to.have.members( [ 'Vibrant code block' ] );
} );

it( 'should detect styles for the div (as container)', () => {
setData( model,
'<htmlDiv>' +
'<paragraph>foo[bar]baz</paragraph>' +
'</htmlDiv>'
);

model.change( writer => {
writer.setAttribute( 'htmlDivAttributes', { classes: [ 'callout' ] }, root.getChild( 0 ) );
} );

expect( command.value ).to.have.members( [ 'Div style' ] );
} );

it( 'should detect styles for the div (as block)', () => {
setData( model,
'<htmlDivParagraph>foo[bar]baz</htmlDivParagraph>'
);

model.change( writer => {
writer.setAttribute( 'htmlDivAttributes', { classes: [ 'callout' ] }, root.getChild( 0 ) );
} );

expect( command.value ).to.have.members( [ 'Div style' ] );
} );

it( 'should not detect styles for elements outside a widget element', () => {
setData( model,
'<blockQuote>' +
Expand Down Expand Up @@ -809,6 +877,48 @@ describe( 'StyleCommand', () => {
);
} );

it( 'should add (and remove) htmlDivAttribute for div as a container', () => {
setData( model,
'<htmlDiv>' +
'<paragraph>foo[]</paragraph>' +
'</htmlDiv>'
);

command.execute( { styleName: 'Div style' } );

expect( getData( model ) ).to.equal(
'<htmlDiv htmlDivAttributes="{"classes":["callout"]}">' +
'<paragraph>foo[]</paragraph>' +
'</htmlDiv>'
);

command.execute( { styleName: 'Div style' } );

expect( getData( model ) ).to.equal(
'<htmlDiv>' +
'<paragraph>foo[]</paragraph>' +
'</htmlDiv>'
);
} );

it( 'should add (and remove) htmlDivAttribute for div as a block', () => {
setData( model,
'<htmlDivParagraph>foo[]</htmlDivParagraph>'
);

command.execute( { styleName: 'Div style' } );

expect( getData( model ) ).to.equal(
'<htmlDivParagraph htmlDivAttributes="{"classes":["callout"]}">foo[]</htmlDivParagraph>'
);

command.execute( { styleName: 'Div style' } );

expect( getData( model ) ).to.equal(
'<htmlDivParagraph>foo[]</htmlDivParagraph>'
);
} );

it( 'should add htmlAttribute only to elements in the same widget element boundaries', () => {
setData( model,
'<blockQuote>' +
Expand Down

0 comments on commit 4b44f58

Please sign in to comment.