diff --git a/packages/ckeditor5-html-support/src/htmlcomment.js b/packages/ckeditor5-html-support/src/htmlcomment.js
index 2302f744ef5..8d1fb221401 100644
--- a/packages/ckeditor5-html-support/src/htmlcomment.js
+++ b/packages/ckeditor5-html-support/src/htmlcomment.js
@@ -31,6 +31,13 @@ export default class HtmlComment extends Plugin {
init() {
const editor = this.editor;
+ // Allow storing comment's content as the $root attribute with the name `$comment:`.
+ editor.model.schema.addAttributeCheck( ( context, attributeName ) => {
+ if ( context.endsWith( '$root' ) && attributeName.startsWith( '$comment' ) ) {
+ return true;
+ }
+ } );
+
// Convert the `$comment` view element to `$comment:` marker and store its content (the comment itself) as a $root
// attribute. The comment content is needed in the `dataDowncast` pipeline to re-create the comment node.
editor.conversion.for( 'upcast' ).elementToMarker( {
diff --git a/packages/ckeditor5-html-support/tests/htmlcomment.js b/packages/ckeditor5-html-support/tests/htmlcomment.js
index 7deb67caee6..cd048d73d29 100644
--- a/packages/ckeditor5-html-support/tests/htmlcomment.js
+++ b/packages/ckeditor5-html-support/tests/htmlcomment.js
@@ -39,6 +39,18 @@ describe( 'HtmlComment', () => {
expect( editor.plugins.get( 'HtmlComment' ) ).to.be.instanceOf( HtmlComment );
} );
+ describe( 'schema', () => {
+ it( 'should allow root attributes containing comment\'s content in the schema', () => {
+ editor.setData( 'Foo
' );
+
+ model.change( writer => {
+ model.schema.removeDisallowedAttributes( [ root ], writer );
+
+ expect( editor.getData() ).to.equal( 'Foo
' );
+ } );
+ } );
+ } );
+
describe( 'upcast conversion', () => {
it( 'should convert each comment node to a collapsed marker', () => {
editor.setData( 'Foo
' );