|
|
@@ -115,122 +115,208 @@ describe( 'DowncastHelpers', () => {
|
|
|
} );
|
|
|
|
|
|
describe( 'config.triggerBy', () => {
|
|
|
- beforeEach( () => {
|
|
|
- model.schema.register( 'complex', {
|
|
|
- allowIn: '$root',
|
|
|
- allowAttributes: [ 'toStyle', 'toClass' ]
|
|
|
+ describe( 'with simple block view structure', () => {
|
|
|
+ beforeEach( () => {
|
|
|
+ model.schema.register( 'simpleBlock', {
|
|
|
+ allowIn: '$root',
|
|
|
+ allowAttributes: [ 'toStyle', 'toClass' ]
|
|
|
+ } );
|
|
|
+ downcastHelpers.elementToElement( {
|
|
|
+ model: 'simpleBlock',
|
|
|
+ view: ( modelElement, { writer } ) => {
|
|
|
+ return writer.createContainerElement( 'div', getViewAttributes( modelElement ) );
|
|
|
+ },
|
|
|
+ triggerBy: [
|
|
|
+ 'attribute:toStyle:simpleBlock',
|
|
|
+ 'attribute:toClass:simpleBlock'
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
- downcastHelpers.elementToElement( {
|
|
|
- model: 'complex',
|
|
|
- view: ( modelElement, { writer } ) => {
|
|
|
- // TODO decide whether below is readable:
|
|
|
- const toStyle = modelElement.hasAttribute( 'toStyle' ) && { style: modelElement.getAttribute( 'toStyle' ) };
|
|
|
- const toClass = modelElement.hasAttribute( 'toClass' ) && { class: 'complex-other' };
|
|
|
|
|
|
- const attributes = {
|
|
|
- ...toStyle,
|
|
|
- ...toClass
|
|
|
- };
|
|
|
+ it( 'should convert on insert', () => {
|
|
|
+ model.change( writer => {
|
|
|
+ writer.insertElement( 'simpleBlock', modelRoot, 0 );
|
|
|
+ } );
|
|
|
|
|
|
- const outter = writer.createContainerElement( 'c-outter' );
|
|
|
- const inner = writer.createContainerElement( 'c-inner', attributes );
|
|
|
+ expectResult( '<div></div>' );
|
|
|
+ } );
|
|
|
|
|
|
- writer.insert( writer.createPositionAt( outter, 0 ), inner );
|
|
|
+ it( 'should converter on attribute set', () => {
|
|
|
+ setModelData( model, '<simpleBlock></simpleBlock>' );
|
|
|
|
|
|
- return outter;
|
|
|
- },
|
|
|
- triggerBy: [
|
|
|
- 'attribute:toStyle:complex',
|
|
|
- 'attribute:toClass:complex'
|
|
|
- ]
|
|
|
- } );
|
|
|
+ model.change( writer => {
|
|
|
+ writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
- model.schema.register( 'paragraph', {
|
|
|
- inheritAllFrom: '$block',
|
|
|
- allowIn: 'complex'
|
|
|
+ expectResult( '<div style="display:block"></div>' );
|
|
|
} );
|
|
|
- downcastHelpers.elementToElement( { model: 'paragraph', view: 'p' } );
|
|
|
- } );
|
|
|
|
|
|
- it( 'should convert to view as normal', () => {
|
|
|
- model.change( writer => {
|
|
|
- writer.insertElement( 'complex', modelRoot, 0 );
|
|
|
+ it( 'should converter on attribute change', () => {
|
|
|
+ setModelData( model, '<simpleBlock toStyle="display:block"></simpleBlock>' );
|
|
|
+
|
|
|
+ model.change( writer => {
|
|
|
+ writer.setAttribute( 'toStyle', 'display:inline', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ expectResult( '<div style="display:inline"></div>' );
|
|
|
} );
|
|
|
|
|
|
- expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
- } );
|
|
|
+ it( 'should convert on attribute remove', () => {
|
|
|
+ setModelData( model, '<simpleBlock toStyle="display:block"></simpleBlock>' );
|
|
|
|
|
|
- it( 'should use main converter for attribute set', () => {
|
|
|
- setModelData( model, '<complex></complex>' );
|
|
|
+ model.change( writer => {
|
|
|
+ writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
- model.change( writer => {
|
|
|
- writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
+ expectResult( '<div></div>' );
|
|
|
} );
|
|
|
|
|
|
- expectResult( '<c-outter><c-inner style="display:block"></c-inner></c-outter>' );
|
|
|
- } );
|
|
|
+ it( 'should convert on one attribute add and other remove', () => {
|
|
|
+ setModelData( model, '<simpleBlock toStyle="display:block"></simpleBlock>' );
|
|
|
|
|
|
- it( 'should use main converter for attribute remove', () => {
|
|
|
- setModelData( model, '<complex toStyle="display:block"></complex>' );
|
|
|
+ model.change( writer => {
|
|
|
+ writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
+ writer.setAttribute( 'toClass', true, modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
- model.change( writer => {
|
|
|
- writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
+ expectResult( '<div class="is-classy"></div>' );
|
|
|
} );
|
|
|
|
|
|
- expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
- } );
|
|
|
+ it( 'should do nothing if other attribute changed', () => {
|
|
|
+ setModelData( model, '<simpleBlock></simpleBlock>' );
|
|
|
|
|
|
- it( 'should use main converter for attribute add & remove', () => {
|
|
|
- setModelData( model, '<complex toStyle="display:block"></complex>' );
|
|
|
+ model.change( writer => {
|
|
|
+ writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
- model.change( writer => {
|
|
|
- writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
- writer.setAttribute( 'toClass', true, modelRoot.getChild( 0 ) );
|
|
|
+ expectResult( '<div></div>' );
|
|
|
} );
|
|
|
-
|
|
|
- expectResult( '<c-outter><c-inner class="complex-other"></c-inner></c-outter>' );
|
|
|
} );
|
|
|
|
|
|
- it( 'should do nothing if other attribute changed', () => {
|
|
|
- setModelData( model, '<complex></complex>' );
|
|
|
+ describe.skip( 'with complex view structure', () => {
|
|
|
+ beforeEach( () => {
|
|
|
+ model.schema.register( 'complex', {
|
|
|
+ allowIn: '$root',
|
|
|
+ allowAttributes: [ 'toStyle', 'toClass' ]
|
|
|
+ } );
|
|
|
+ downcastHelpers.elementToElement( {
|
|
|
+ model: 'complex',
|
|
|
+ view: ( modelElement, conversionApi ) => {
|
|
|
+ const { writer, mapper } = conversionApi;
|
|
|
+ const outter = writer.createContainerElement( 'c-outter' );
|
|
|
+ mapper.bindElements( modelElement, outter );
|
|
|
+ const inner = writer.createContainerElement( 'c-inner', getViewAttributes( modelElement ) );
|
|
|
|
|
|
- model.change( writer => {
|
|
|
- writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
|
|
|
+ writer.insert( writer.createPositionAt( outter, 0 ), inner );
|
|
|
+ mapper.bindSlotElements( modelElement, inner );
|
|
|
+
|
|
|
+ return outter;
|
|
|
+ },
|
|
|
+ triggerBy: [
|
|
|
+ 'attribute:toStyle:complex',
|
|
|
+ 'attribute:toClass:complex'
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ model.schema.register( 'paragraph', {
|
|
|
+ inheritAllFrom: '$block',
|
|
|
+ allowIn: 'complex'
|
|
|
+ } );
|
|
|
+ downcastHelpers.elementToElement( { model: 'paragraph', view: 'p' } );
|
|
|
} );
|
|
|
|
|
|
- expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
- } );
|
|
|
+ it( 'should convert to view on insert', () => {
|
|
|
+ model.change( writer => {
|
|
|
+ writer.insertElement( 'complex', modelRoot, 0 );
|
|
|
+ } );
|
|
|
|
|
|
- describe( 'memoization', () => {
|
|
|
- it( 'should create new element on re-converting element', () => {
|
|
|
- setModelData( model, '<complex></complex>' );
|
|
|
+ expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
+ } );
|
|
|
|
|
|
- const renderedView = viewRoot.getChild( 0 );
|
|
|
+ it( 'should use main converter for attribute set', () => {
|
|
|
+ setModelData( model, '<complex></complex>' );
|
|
|
|
|
|
model.change( writer => {
|
|
|
writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
} );
|
|
|
|
|
|
- const viewAfterReRender = viewRoot.getChild( 0 );
|
|
|
+ expectResult( '<c-outter><c-inner style="display:block"></c-inner></c-outter>' );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should use main converter for attribute remove', () => {
|
|
|
+ setModelData( model, '<complex toStyle="display:block"></complex>' );
|
|
|
+
|
|
|
+ model.change( writer => {
|
|
|
+ writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
|
|
|
- expect( viewAfterReRender ).to.not.equal( renderedView );
|
|
|
+ expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
} );
|
|
|
|
|
|
- it( 'should not re-create child elements on re-converting element', () => {
|
|
|
- setModelData( model, '<complex><paragraph>Foo bar baz</paragraph></complex>' );
|
|
|
+ it( 'should use main converter for attribute add & remove', () => {
|
|
|
+ setModelData( model, '<complex toStyle="display:block"></complex>' );
|
|
|
|
|
|
- expectResult( '<complex><p>Foo bar baz</p></complex>' );
|
|
|
- const renderedViewView = viewRoot.getChild( 0 ).getChild( 0 );
|
|
|
+ model.change( writer => {
|
|
|
+ writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
|
|
|
+ writer.setAttribute( 'toClass', true, modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ expectResult( '<c-outter><c-inner class="is-classy"></c-inner></c-outter>' );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should do nothing if other attribute changed', () => {
|
|
|
+ setModelData( model, '<complex></complex>' );
|
|
|
|
|
|
model.change( writer => {
|
|
|
- writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
+ writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
|
|
|
} );
|
|
|
|
|
|
- const viewAfterReRender = viewRoot.getChild( 0 ).getChild( 0 );
|
|
|
+ expectResult( '<c-outter><c-inner></c-inner></c-outter>' );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'memoization', () => {
|
|
|
+ it( 'should create new element on re-converting element', () => {
|
|
|
+ setModelData( model, '<complex></complex>' );
|
|
|
+
|
|
|
+ const renderedView = viewRoot.getChild( 0 );
|
|
|
+
|
|
|
+ model.change( writer => {
|
|
|
+ writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ const viewAfterReRender = viewRoot.getChild( 0 );
|
|
|
+
|
|
|
+ expect( viewAfterReRender ).to.not.equal( renderedView );
|
|
|
+ } );
|
|
|
|
|
|
- expect( viewAfterReRender ).to.equal( renderedViewView );
|
|
|
+ it( 'should not re-create child elements on re-converting element', () => {
|
|
|
+ setModelData( model, '<complex><paragraph>Foo bar baz</paragraph></complex>' );
|
|
|
+
|
|
|
+ expectResult( '<c-outter><c-inner><p>Foo bar baz</p></c-inner></c-outter>' );
|
|
|
+ const renderedViewView = viewRoot.getChild( 0 ).getChild( 0 );
|
|
|
+
|
|
|
+ model.change( writer => {
|
|
|
+ writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ const viewAfterReRender = viewRoot.getChild( 0 ).getChild( 0 );
|
|
|
+
|
|
|
+ expect( viewAfterReRender ).to.equal( renderedViewView );
|
|
|
+ } );
|
|
|
} );
|
|
|
} );
|
|
|
+
|
|
|
+ function getViewAttributes( modelElement ) {
|
|
|
+ // TODO decide whether below is readable:
|
|
|
+ const toStyle = modelElement.hasAttribute( 'toStyle' ) && { style: modelElement.getAttribute( 'toStyle' ) };
|
|
|
+ const toClass = modelElement.hasAttribute( 'toClass' ) && { class: 'is-classy' };
|
|
|
+
|
|
|
+ const attributes = {
|
|
|
+ ...toStyle,
|
|
|
+ ...toClass
|
|
|
+ };
|
|
|
+ return attributes;
|
|
|
+ }
|
|
|
} );
|
|
|
} );
|
|
|
|