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

Commit

Permalink
Merge branch 'master' into t/ckeditor5/1514
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Sep 9, 2019
2 parents a0a8e6e + 62fe3e1 commit 9bc00da
Show file tree
Hide file tree
Showing 87 changed files with 2,032 additions and 581 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
Changelog
=========

## [14.0.0](https://github.com/ckeditor/ckeditor5-engine/compare/v13.2.1...v14.0.0) (2019-08-26)

### Features

* `transformSets()` will now return a `Map` instance linking transformed operations to the original operations. ([61da3ec](https://github.com/ckeditor/ckeditor5-engine/commit/61da3ec))
* Brought support for RTL content in the `bindTwoStepCaretToAttribute()` helper. See [ckeditor/ckeditor5#1151](https://github.com/ckeditor/ckeditor5/issues/1151). ([d57ff5a](https://github.com/ckeditor/ckeditor5-engine/commit/d57ff5a))
* Introduced `model.Differ#refreshItem()`. ([7dc8710](https://github.com/ckeditor/ckeditor5-engine/commit/7dc8710))
* Introduced the `is()` method to additional objects from the model and view realms. Closes [#1667](https://github.com/ckeditor/ckeditor5-engine/issues/1667). ([89dbe43](https://github.com/ckeditor/ckeditor5-engine/commit/89dbe43))

### Bug fixes

* Fixed problem with handling very large text nodes. ([a7ae813](https://github.com/ckeditor/ckeditor5-engine/commit/a7ae813))
* Prevented `Differ` crashing in some scenarios involving attribute changes on elements. Closes [#1764](https://github.com/ckeditor/ckeditor5-engine/issues/1764). ([482e55e](https://github.com/ckeditor/ckeditor5-engine/commit/482e55e))

### Other changes

* Add `unwrapElement()` method to UpcastWriter. ([9e97196](https://github.com/ckeditor/ckeditor5-engine/commit/9e97196))
* Allowed for unbinding single elements from a marker name in `Mapper`. Closes [#1758](https://github.com/ckeditor/ckeditor5-engine/issues/1758). ([52e701d](https://github.com/ckeditor/ckeditor5-engine/commit/52e701d))
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([6ed94c6](https://github.com/ckeditor/ckeditor5-engine/commit/6ed94c6))
* Introduced automatic marker re-rendering during conversion for markers which view element was unbound. Closes [#1780](https://github.com/ckeditor/ckeditor5-engine/issues/1780). ([5661fb6](https://github.com/ckeditor/ckeditor5-engine/commit/5661fb6))
* Position getters (such as `#parent` or `#index`) will throw when position points at an incorrect place in its root. Closes [#1776](https://github.com/ckeditor/ckeditor5-engine/issues/1776). ([a359866](https://github.com/ckeditor/ckeditor5-engine/commit/a359866))

### BREAKING CHANGES

* New parameter introduced in `DowncastDispatcher#convertChanges()`. Now it is `convertChanges( differ, markers, writer )`.
* Although it was rather impossible to use `DowncastDispatcher` without specifying any conversion API in the constructor, now it is a required parameter.
* The `bindTwoStepCaretToAttribute()` helper arguments syntax has changed (replaced by an object). Please refer to the helper documentation to learn more.
* `Mapper#unbindElementsFromMarkerName( markerName )` was replaced by `Mapper#unbindElementFromMarkerName( element, markerName )`.


## [13.2.1](https://github.com/ckeditor/ckeditor5-engine/compare/v13.2.0...v13.2.1) (2019-07-10)

Internal changes only (updated dependencies, documentation, etc.).
Expand Down
2 changes: 1 addition & 1 deletion docs/api/engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ The source code of this package is available on GitHub in https://github.com/cke

* [`@ckeditor/ckeditor5-engine` on npm](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)
* [`ckeditor/ckeditor5-engine` on GitHub](https://github.com/ckeditor/ckeditor5-engine)
* [Issue tracker](https://github.com/ckeditor/ckeditor5-engine/issues)
* [Issue tracker](https://github.com/ckeditor/ckeditor5/issues)
* [Changelog](https://github.com/ckeditor/ckeditor5-engine/blob/master/CHANGELOG.md)
34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ckeditor/ckeditor5-engine",
"version": "13.2.1",
"version": "14.0.0",
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.",
"keywords": [
"wysiwyg",
Expand All @@ -21,24 +21,24 @@
"ckeditor 5"
],
"dependencies": {
"@ckeditor/ckeditor5-utils": "^13.0.1",
"@ckeditor/ckeditor5-utils": "^14.0.0",
"lodash-es": "^4.17.10"
},
"devDependencies": {
"@ckeditor/ckeditor5-basic-styles": "^11.1.3",
"@ckeditor/ckeditor5-block-quote": "^11.1.2",
"@ckeditor/ckeditor5-core": "^12.2.1",
"@ckeditor/ckeditor5-editor-classic": "^12.1.3",
"@ckeditor/ckeditor5-enter": "^11.0.4",
"@ckeditor/ckeditor5-essentials": "^11.0.4",
"@ckeditor/ckeditor5-heading": "^11.0.4",
"@ckeditor/ckeditor5-link": "^11.1.1",
"@ckeditor/ckeditor5-list": "^12.0.4",
"@ckeditor/ckeditor5-paragraph": "^11.0.4",
"@ckeditor/ckeditor5-theme-lark": "^14.1.1",
"@ckeditor/ckeditor5-typing": "^12.1.1",
"@ckeditor/ckeditor5-undo": "^11.0.4",
"@ckeditor/ckeditor5-widget": "^11.0.4",
"@ckeditor/ckeditor5-basic-styles": "^11.1.4",
"@ckeditor/ckeditor5-block-quote": "^11.1.3",
"@ckeditor/ckeditor5-core": "^12.3.0",
"@ckeditor/ckeditor5-editor-classic": "^12.1.4",
"@ckeditor/ckeditor5-enter": "^11.1.0",
"@ckeditor/ckeditor5-essentials": "^11.0.5",
"@ckeditor/ckeditor5-heading": "^11.0.5",
"@ckeditor/ckeditor5-link": "^11.1.2",
"@ckeditor/ckeditor5-list": "^12.1.0",
"@ckeditor/ckeditor5-paragraph": "^11.0.5",
"@ckeditor/ckeditor5-theme-lark": "^14.2.0",
"@ckeditor/ckeditor5-typing": "^12.2.0",
"@ckeditor/ckeditor5-undo": "^11.0.5",
"@ckeditor/ckeditor5-widget": "^11.1.0",
"eslint": "^5.5.0",
"eslint-config-ckeditor5": "^2.0.0",
"husky": "^1.3.1",
Expand All @@ -51,7 +51,7 @@
"author": "CKSource (http://cksource.com/)",
"license": "GPL-2.0-or-later",
"homepage": "https://ckeditor.com/ckeditor-5",
"bugs": "https://github.com/ckeditor/ckeditor5-engine/issues",
"bugs": "https://github.com/ckeditor/ckeditor5/issues",
"repository": {
"type": "git",
"url": "https://github.com/ckeditor/ckeditor5-engine.git"
Expand Down
2 changes: 1 addition & 1 deletion src/controller/editingcontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default class EditingController {
// Also convert model selection.
this.listenTo( doc, 'change', () => {
this.view.change( writer => {
this.downcastDispatcher.convertChanges( doc.differ, writer );
this.downcastDispatcher.convertChanges( doc.differ, markers, writer );
this.downcastDispatcher.convertSelection( selection, markers, writer );
} );
}, { priority: 'low' } );
Expand Down
25 changes: 15 additions & 10 deletions src/conversion/downcastdispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ export default class DowncastDispatcher {
* Creates a `DowncastDispatcher` instance.
*
* @see module:engine/conversion/downcastdispatcher~DowncastConversionApi
* @param {Object} [conversionApi] Additional properties for interface that will be passed to events fired
* @param {Object} conversionApi Additional properties for interface that will be passed to events fired
* by `DowncastDispatcher`.
*/
constructor( conversionApi = {} ) {
constructor( conversionApi ) {
/**
* Interface passed by dispatcher to the events callbacks.
*
Expand All @@ -122,9 +122,10 @@ export default class DowncastDispatcher {
* Takes {@link module:engine/model/differ~Differ model differ} object with buffered changes and fires conversion basing on it.
*
* @param {module:engine/model/differ~Differ} differ Differ object with buffered changes.
* @param {module:engine/model/markercollection~MarkerCollection} markers Markers connected with converted model.
* @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.
*/
convertChanges( differ, writer ) {
convertChanges( differ, markers, writer ) {
// Before the view is updated, remove markers which have changed.
for ( const change of differ.getMarkersToRemove() ) {
this.convertMarkerRemove( change.name, change.range, writer );
Expand All @@ -142,6 +143,13 @@ export default class DowncastDispatcher {
}
}

for ( const markerName of this.conversionApi.mapper.flushUnboundMarkerNames() ) {
const markerRange = markers.get( markerName ).getRange();

this.convertMarkerRemove( markerName, markerRange, writer );
this.convertMarkerAdd( markerName, markerRange, writer );
}

// After the view is updated, convert markers which have changed.
for ( const change of differ.getMarkersToAdd() ) {
this.convertMarkerAdd( change.name, change.range, writer );
Expand Down Expand Up @@ -252,7 +260,7 @@ export default class DowncastDispatcher {
* @fires addMarker
* @fires attribute
* @param {module:engine/model/selection~Selection} selection Selection to convert.
* @param {Array.<module:engine/model/markercollection~Marker>} markers Array of markers containing model markers.
* @param {module:engine/model/markercollection~MarkerCollection} markers Markers connected with converted model.
* @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.
*/
convertSelection( selection, markers, writer ) {
Expand Down Expand Up @@ -532,7 +540,6 @@ export default class DowncastDispatcher {
* @param {String} data.attributeKey Attribute key.
* @param {*} data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.
* @param {*} data.attributeNewValue New attribute value.
* @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.
* @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface
* to be used by callback, passed in `DowncastDispatcher` constructor.
*/
Expand All @@ -542,7 +549,6 @@ export default class DowncastDispatcher {
*
* @event selection
* @param {module:engine/model/selection~Selection} selection Selection that is converted.
* @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.
* @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface
* to be used by callback, passed in `DowncastDispatcher` constructor.
*/
Expand All @@ -558,17 +564,17 @@ export default class DowncastDispatcher {
* If the marker range is not collapsed:
*
* * the event is fired for each item in the marker range one by one,
* * consumables object includes each item of the marker range and the consumable value is same as event name.
* * `conversionApi.consumable` includes each item of the marker range and the consumable value is same as event name.
*
* If the marker range is collapsed:
*
* * there is only one event,
* * consumables object includes marker range with event name.
* * `conversionApi.consumable` includes marker range with event name.
*
* If selection inside a marker is converted:
*
* * there is only one event,
* * consumables object includes selection instance with event name.
* * `conversionApi.consumable` includes selection instance with event name.
*
* @event addMarker
* @param {Object} data Additional information about the change.
Expand All @@ -578,7 +584,6 @@ export default class DowncastDispatcher {
* the marker range was not collapsed.
* @param {module:engine/model/range~Range} data.markerRange Marker range.
* @param {String} data.markerName Marker name.
* @param {module:engine/conversion/modelconsumable~ModelConsumable} consumable Values to consume.
* @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface
* to be used by callback, passed in `DowncastDispatcher` constructor.
*/
Expand Down
64 changes: 59 additions & 5 deletions src/conversion/mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,25 @@ export default class Mapper {
*/
this._markerNameToElements = new Map();

/**
* View element to model marker names mapping.
*
* This is reverse to {@link ~Mapper#_markerNameToElements} map.
*
* @private
* @member {Map}
*/
this._elementToMarkerNames = new Map();

/**
* Stores marker names of markers which has changed due to unbinding a view element (so it is assumed that the view element
* has been removed, moved or renamed).
*
* @private
* @member {Set.<module:engine/model/markercollection~Marker>}
*/
this._unboundMarkerNames = new Set();

// Default mapper algorithm for mapping model position to view position.
this.on( 'modelToViewPosition', ( evt, data ) => {
if ( data.viewPosition ) {
Expand Down Expand Up @@ -132,6 +151,12 @@ export default class Mapper {

this._viewToModelMapping.delete( viewElement );

if ( this._elementToMarkerNames.has( viewElement ) ) {
for ( const markerName of this._elementToMarkerNames.get( viewElement ) ) {
this._unboundMarkerNames.add( markerName );
}
}

if ( this._modelToViewMapping.get( modelElement ) == viewElement ) {
this._modelToViewMapping.delete( modelElement );
}
Expand Down Expand Up @@ -167,10 +192,13 @@ export default class Mapper {
*/
bindElementToMarker( element, name ) {
const elements = this._markerNameToElements.get( name ) || new Set();

elements.add( element );

const names = this._elementToMarkerNames.get( element ) || new Set();
names.add( name );

this._markerNameToElements.set( name, elements );
this._elementToMarkerNames.set( element, names );
}

/**
Expand All @@ -180,15 +208,39 @@ export default class Mapper {
* @param {String} name Marker name.
*/
unbindElementFromMarkerName( element, name ) {
const elements = this._markerNameToElements.get( name );
const nameToElements = this._markerNameToElements.get( name );

if ( elements ) {
elements.delete( element );
if ( nameToElements ) {
nameToElements.delete( element );

if ( elements.size == 0 ) {
if ( nameToElements.size == 0 ) {
this._markerNameToElements.delete( name );
}
}

const elementToNames = this._elementToMarkerNames.get( element );

if ( elementToNames ) {
elementToNames.delete( name );

if ( elementToNames.size == 0 ) {
this._elementToMarkerNames.delete( element );
}
}
}

/**
* Returns all marker names of markers which has changed due to unbinding a view element (so it is assumed that the view element
* has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.
*
* @returns {Array.<String>}
*/
flushUnboundMarkerNames() {
const markerNames = Array.from( this._unboundMarkerNames );

this._unboundMarkerNames.clear();

return markerNames;
}

/**
Expand All @@ -198,6 +250,8 @@ export default class Mapper {
this._modelToViewMapping = new WeakMap();
this._viewToModelMapping = new WeakMap();
this._markerNameToElements = new Map();
this._elementToMarkerNames = new Map();
this._unboundMarkerNames = new Set();
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/conversion/upcastdispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,27 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
* }
* } );
*
* // Convert <p>'s font-size style.
* // Note: You should use a low-priority observer in order to ensure that
* // it's executed after the element-to-element converter.
* editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {
* const { consumable, schema, writer } = conversionApi;
*
* if ( !consumable.consume( data.viewItem, { style: 'font-size' } ) ) {
* return;
* }
*
* const fontSize = data.viewItem.getStyle( 'font-size' );
*
* // Don't go for the model element after data.modelCursor because it might happen
* // that a single view element was converted to multiple model elements. Get all of them.
* for ( const item of data.modelRange.getItems( { shallow: true } ) ) {
* if ( schema.checkAttribute( item, 'fontSize' ) ) {
* writer.setAttribute( 'fontSize', fontSize, item );
* }
* }
* }, { priority: 'low' } );
*
* // Convert all elements which have no custom converter into paragraph (autoparagraphing).
* editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {
* // When element is already consumed by higher priority converters then do nothing.
Expand Down
Loading

0 comments on commit 9bc00da

Please sign in to comment.