Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Moved consumable parameter to conversionApi parameter in downcast #1314

Merged
merged 2 commits into from
Feb 20, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 23 additions & 24 deletions src/conversion/downcast-converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,10 +431,9 @@ function _normalizeToAttributeConfig( view ) {
*
* downcastDispatcher.on(
* 'insert:myElem',
* insertElement( ( modelItem, consumable, conversionApi ) => {
* const writer = conversionApi.writer;
* const text = writer.createText( 'myText' );
* const myElem = writer.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
* insertElement( ( modelItem, viewWriter ) => {
* const text = viewWriter.createText( 'myText' );
* const myElem = viewWriter.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
*
* // Do something fancy with myElem using `modelItem` or other parameters.
*
Expand All @@ -446,14 +445,14 @@ function _normalizeToAttributeConfig( view ) {
* @returns {Function} Insert element event converter.
*/
export function insertElement( elementCreator ) {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
const viewElement = elementCreator( data.item, conversionApi.writer );

if ( !viewElement ) {
return;
}

if ( !consumable.consume( data.item, 'insert' ) ) {
if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
return;
}

Expand All @@ -475,8 +474,8 @@ export function insertElement( elementCreator ) {
* @returns {Function} Insert text event converter.
*/
export function insertText() {
return ( evt, data, consumable, conversionApi ) => {
if ( !consumable.consume( data.item, 'insert' ) ) {
return ( evt, data, conversionApi ) => {
if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
return;
}

Expand Down Expand Up @@ -530,7 +529,7 @@ export function remove() {
* @returns {Function} Insert element event converter.
*/
export function insertUIElement( elementCreator ) {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
// Create two view elements. One will be inserted at the beginning of marker, one at the end.
// If marker is collapsed, only "opening" element will be inserted.
data.isOpening = true;
Expand All @@ -548,13 +547,13 @@ export function insertUIElement( elementCreator ) {
// Marker that is collapsed has consumable build differently that non-collapsed one.
// For more information see `addMarker` event description.
// If marker's range is collapsed - check if it can be consumed.
if ( markerRange.isCollapsed && !consumable.consume( markerRange, evt.name ) ) {
if ( markerRange.isCollapsed && !conversionApi.consumable.consume( markerRange, evt.name ) ) {
return;
}

// If marker's range is not collapsed - consume all items inside.
for ( const value of markerRange ) {
if ( !consumable.consume( value.item, evt.name ) ) {
if ( !conversionApi.consumable.consume( value.item, evt.name ) ) {
return;
}
}
Expand Down Expand Up @@ -646,8 +645,8 @@ export function removeUIElement( elementCreator ) {
export function changeAttribute( attributeCreator ) {
attributeCreator = attributeCreator || ( ( value, data ) => ( { value, key: data.attributeKey } ) );

return ( evt, data, consumable, conversionApi ) => {
if ( !consumable.consume( data.item, evt.name ) ) {
return ( evt, data, conversionApi ) => {
if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
return;
}

Expand Down Expand Up @@ -676,7 +675,7 @@ export function changeAttribute( attributeCreator ) {
}

// Then, if conversion was successful, set the new attribute.
const newAttribute = attributeCreator( data.attributeNewValue, data, consumable, conversionApi );
const newAttribute = attributeCreator( data.attributeNewValue, data );

if ( data.attributeNewValue !== null && newAttribute ) {
if ( newAttribute.key == 'class' ) {
Expand Down Expand Up @@ -721,15 +720,15 @@ export function changeAttribute( attributeCreator ) {
* The converter automatically consumes corresponding value from consumables list, stops the event (see
* {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).
*
* modelDispatcher.on( 'attribute:bold', wrapItem( ( attributeValue, data, consumable, conversionApi ) => {
* return conversionApi.writer.createAttributeElement( 'strong' );
* modelDispatcher.on( 'attribute:bold', wrapItem( ( modelAttributeValue, viewWriter ) => {
* return viewWriter.createAttributeElement( 'strong' );
* } );
*
* @param {Function} elementCreator Function returning a view element, which will be used for wrapping.
* @returns {Function} Set/change attribute converter.
*/
export function wrap( elementCreator ) {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
// Recreate current wrapping node. It will be used to unwrap view range if the attribute value has changed
// or the attribute was removed.
const oldViewElement = elementCreator( data.attributeOldValue, conversionApi.writer );
Expand All @@ -741,7 +740,7 @@ export function wrap( elementCreator ) {
return;
}

if ( !consumable.consume( data.item, evt.name ) ) {
if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
return;
}

Expand Down Expand Up @@ -783,7 +782,7 @@ export function wrap( elementCreator ) {
* @return {Function}
*/
export function highlightText( highlightDescriptor ) {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
if ( data.markerRange.isCollapsed ) {
return;
}
Expand All @@ -798,7 +797,7 @@ export function highlightText( highlightDescriptor ) {
return;
}

if ( !consumable.consume( data.item, evt.name ) ) {
if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
return;
}

Expand Down Expand Up @@ -833,7 +832,7 @@ export function highlightText( highlightDescriptor ) {
* @return {Function}
*/
export function highlightElement( highlightDescriptor ) {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
if ( data.markerRange.isCollapsed ) {
return;
}
Expand All @@ -848,19 +847,19 @@ export function highlightElement( highlightDescriptor ) {
return;
}

if ( !consumable.test( data.item, evt.name ) ) {
if ( !conversionApi.consumable.test( data.item, evt.name ) ) {
return;
}

const viewElement = conversionApi.mapper.toViewElement( data.item );

if ( viewElement && viewElement.getCustomProperty( 'addHighlight' ) ) {
// Consume element itself.
consumable.consume( data.item, evt.name );
conversionApi.consumable.consume( data.item, evt.name );

// Consume all children nodes.
for ( const value of ModelRange.createIn( data.item ) ) {
consumable.consume( value.item, evt.name );
conversionApi.consumable.consume( value.item, evt.name );
}

viewElement.getCustomProperty( 'addHighlight' )( viewElement, descriptor, conversionApi.writer );
Expand Down
12 changes: 6 additions & 6 deletions src/conversion/downcast-selection-converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
* @returns {Function} Selection converter.
*/
export function convertRangeSelection() {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
const selection = data.selection;

if ( selection.isCollapsed ) {
return;
}

if ( !consumable.consume( selection, 'selection' ) ) {
if ( !conversionApi.consumable.consume( selection, 'selection' ) ) {
return;
}

Expand Down Expand Up @@ -66,14 +66,14 @@ export function convertRangeSelection() {
* @returns {Function} Selection converter.
*/
export function convertCollapsedSelection() {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
const selection = data.selection;

if ( !selection.isCollapsed ) {
return;
}

if ( !consumable.consume( selection, 'selection' ) ) {
if ( !conversionApi.consumable.consume( selection, 'selection' ) ) {
return;
}

Expand Down Expand Up @@ -111,7 +111,7 @@ export function convertCollapsedSelection() {
* @returns {Function} Selection converter.
*/
export function clearAttributes() {
return ( evt, data, consumable, conversionApi ) => {
return ( evt, data, conversionApi ) => {
const viewWriter = conversionApi.writer;
const viewSelection = viewWriter.document.selection;

Expand All @@ -133,5 +133,5 @@ export function clearAttributes() {
* {@link module:engine/model/selection~Selection model selection} conversion.
*/
export function clearFakeSelection() {
return ( evt, data, consumable, conversionApi ) => conversionApi.writer.setFakeSelection( false );
return ( evt, data, conversionApi ) => conversionApi.writer.setFakeSelection( false );
}
61 changes: 42 additions & 19 deletions src/conversion/downcastdispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ import extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';
* Example of a custom converter for `DowncastDispatcher`:
*
* // We will convert inserting "paragraph" model element into the model.
* downcastDispatcher.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {
* downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {
* // Remember to check whether the change has not been consumed yet and consume it.
* if ( consumable.consume( data.item, 'insert' ) ) {
* if ( conversionApi.consumable.consume( data.item, 'insert' ) ) {
* return;
* }
*
Expand Down Expand Up @@ -180,6 +180,8 @@ export default class DowncastDispatcher {
this._testAndFire( `attribute:${ key }`, data, consumable );
}
}

this._clearConversionApi();
}

/**
Expand All @@ -194,6 +196,8 @@ export default class DowncastDispatcher {
this.conversionApi.writer = writer;

this.fire( 'remove:' + name, { position, length }, this.conversionApi );

this._clearConversionApi();
}

/**
Expand Down Expand Up @@ -228,6 +232,8 @@ export default class DowncastDispatcher {

this._testAndFire( `attribute:${ key }`, data, consumable );
}

this._clearConversionApi();
}

/**
Expand All @@ -239,16 +245,16 @@ export default class DowncastDispatcher {
* @fires addMarker
* @fires attribute
* @param {module:engine/model/selection~Selection} selection Selection to convert.
* @param {module:engine/model/selection~Selection} Array<module:engine/model/markercollection~Marker> markers
* Array of markers containing model markers.
* @param {Array.<module:engine/model/markercollection~Marker>} markers Array of markers containing model markers.
* @param {module:engine/view/writer~Writer} writer View writer that should be used to modify view document.
*/
convertSelection( selection, markers, writer ) {
this.conversionApi.writer = writer;
const markersAtSelection = Array.from( markers.getMarkersAtPosition( selection.getFirstPosition() ) );
const consumable = this._createSelectionConsumable( selection, markersAtSelection );

this.fire( 'selection', { selection }, consumable, this.conversionApi );
this.conversionApi.writer = writer;
this.conversionApi.consumable = this._createSelectionConsumable( selection, markersAtSelection );

this.fire( 'selection', { selection }, this.conversionApi );

if ( !selection.isCollapsed ) {
return;
Expand All @@ -267,8 +273,8 @@ export default class DowncastDispatcher {
markerRange
};

if ( consumable.test( selection, 'addMarker:' + marker.name ) ) {
this.fire( 'addMarker:' + marker.name, data, consumable, this.conversionApi );
if ( this.conversionApi.consumable.test( selection, 'addMarker:' + marker.name ) ) {
this.fire( 'addMarker:' + marker.name, data, this.conversionApi );
}
}

Expand All @@ -282,10 +288,12 @@ export default class DowncastDispatcher {
};

// Do not fire event if the attribute has been consumed.
if ( consumable.test( selection, 'attribute:' + data.attributeKey ) ) {
this.fire( 'attribute:' + data.attributeKey, data, consumable, this.conversionApi );
if ( this.conversionApi.consumable.test( selection, 'attribute:' + data.attributeKey ) ) {
this.fire( 'attribute:' + data.attributeKey, data, this.conversionApi );
}
}

this._clearConversionApi();
}

/**
Expand Down Expand Up @@ -313,28 +321,29 @@ export default class DowncastDispatcher {
const consumable = new Consumable();
consumable.add( markerRange, eventName );

this.fire( eventName, {
markerName,
markerRange
}, consumable, this.conversionApi );
this.conversionApi.consumable = consumable;

this.fire( eventName, { markerName, markerRange }, this.conversionApi );

return;
}

// Create consumable for each item in range.
const consumable = this._createConsumableForRange( markerRange, eventName );
this.conversionApi.consumable = this._createConsumableForRange( markerRange, eventName );

// Create separate event for each node in the range.
for ( const item of markerRange.getItems() ) {
// Do not fire event for already consumed items.
if ( !consumable.test( item, eventName ) ) {
if ( !this.conversionApi.consumable.test( item, eventName ) ) {
continue;
}

const data = { item, range: Range.createOn( item ), markerName, markerRange };

this.fire( eventName, data, consumable, this.conversionApi );
this.fire( eventName, data, this.conversionApi );
}

this._clearConversionApi();
}

/**
Expand All @@ -354,6 +363,8 @@ export default class DowncastDispatcher {
this.conversionApi.writer = writer;

this.fire( 'removeMarker:' + markerName, { markerName, markerRange }, this.conversionApi );

this._clearConversionApi();
}

/**
Expand Down Expand Up @@ -440,7 +451,19 @@ export default class DowncastDispatcher {

const name = data.item.name || '$text';

this.fire( type + ':' + name, data, consumable, this.conversionApi );
this.conversionApi.consumable = consumable;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will be cleaner if you do this when you create consumable and do not pass consumable to _testAndFire.


this.fire( type + ':' + name, data, this.conversionApi );
}

/**
* Clears conversion API object.
*
* @private
*/
_clearConversionApi() {
delete this.conversionApi.writer;
delete this.conversionApi.consumable;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/conversion/modelconsumable.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ import TextProxy from '../model/textproxy';
* // ├─ <img />
* // └─ <caption>
* // └─ foo
* modelConversionDispatcher.on( 'insert:image', ( evt, data, consumable, conversionApi ) => {
* modelConversionDispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {
* // First, consume the `image` element.
* consumable.consume( data.item, 'insert' );
* conversionApi.consumable.consume( data.item, 'insert' );
*
* // Just create normal image element for the view.
* // Maybe it will be "decorated" later.
Expand All @@ -69,7 +69,7 @@ import TextProxy from '../model/textproxy';
* // `modelCaption` insertion change is consumed from consumable values.
* // It will not be converted by other converters, but it's children (probably some text) will be.
* // Through mapping, converters for text will know where to insert contents of `modelCaption`.
* if ( consumable.consume( modelCaption, 'insert' ) ) {
* if ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {
* const viewCaption = new ViewElement( 'figcaption' );
*
* const viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );
Expand Down
Loading