From d61c6be3c910f97ef2a9f2297aae7d50803cf098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Wr=C3=B3bel?= Date: Mon, 6 Aug 2018 16:53:31 +0200 Subject: [PATCH] Internal: Changed the way of data serialization. --- src/dev-utils/enableenginedebug.js | 4 ++-- src/model/node.js | 6 +++++- src/model/operation/attributeoperation.js | 11 +++++++++++ src/model/operation/detachoperation.js | 11 +++++++++++ src/model/operation/insertoperation.js | 12 ++++++++++++ src/model/operation/markeroperation.js | 8 ++++++++ src/model/operation/mergeoperation.js | 13 +++++++++++++ src/model/operation/moveoperation.js | 12 ++++++++++++ src/model/operation/operation.js | 6 +++--- src/model/operation/renameoperation.js | 11 +++++++++++ src/model/operation/rootattributeoperation.js | 13 ++++++++++++- src/model/operation/splitoperation.js | 15 +++++++++++++++ src/model/operation/unwrapoperation.js | 12 ++++++++++++ src/model/operation/wrapoperation.js | 15 +++++++++++++++ src/model/position.js | 15 +++++++++++++-- src/model/range.js | 12 ++++++++++++ tests/dev-utils/enableenginedebug.js | 2 +- tests/model/_utils/utils.js | 9 --------- tests/model/document.js | 3 +-- tests/model/documentfragment.js | 9 ++++----- tests/model/element.js | 18 ++++++++++-------- tests/model/nodelist.js | 5 ++--- tests/model/operation/attributeoperation.js | 8 ++++---- tests/model/operation/detachoperation.js | 5 ++--- tests/model/operation/insertoperation.js | 9 ++++----- tests/model/operation/markeroperation.js | 9 ++++----- tests/model/operation/moveoperation.js | 9 ++++----- tests/model/operation/nooperation.js | 5 ++--- tests/model/operation/operation.js | 7 +++---- tests/model/operation/reinsertoperation.js | 9 ++++----- tests/model/operation/removeoperation.js | 9 ++++----- tests/model/operation/renameoperation.js | 7 +++---- .../model/operation/rootattributeoperation.js | 8 ++++---- tests/model/position.js | 5 ++--- tests/model/range.js | 16 ++++++++++++++-- tests/model/text.js | 9 ++++----- tests/model/utils-tests/utils.js | 17 ----------------- 37 files changed, 243 insertions(+), 111 deletions(-) diff --git a/src/dev-utils/enableenginedebug.js b/src/dev-utils/enableenginedebug.js index a1f990100..4fa74e86d 100644 --- a/src/dev-utils/enableenginedebug.js +++ b/src/dev-utils/enableenginedebug.js @@ -446,7 +446,7 @@ function enableReplayerTools() { this._appliedOperations = []; } - this._appliedOperations.push( operation.toJSON() ); + this._appliedOperations.push( operation ); return _modelApplyOperation.call( this, operation ); } ); @@ -474,7 +474,7 @@ function enableDocumentTools() { this._operationLogs = []; } - this._operationLogs.push( JSON.stringify( operation.toJSON() ) ); + this._operationLogs.push( JSON.stringify( operation ) ); return _modelApplyOperation.call( this, operation ); } ); diff --git a/src/model/node.js b/src/model/node.js index 9e97281fc..ebdbb0337 100644 --- a/src/model/node.js +++ b/src/model/node.js @@ -381,7 +381,11 @@ export default class Node { const json = {}; if ( this._attrs.size ) { - json.attributes = [ ...this._attrs ]; + json.attributes = Array.from( this._attrs ).reduce( ( result, attr ) => { + result[ attr[ 0 ] ] = attr[ 1 ]; + + return result; + }, {} ); } return json; diff --git a/src/model/operation/attributeoperation.js b/src/model/operation/attributeoperation.js index 1402944aa..206ac12fc 100644 --- a/src/model/operation/attributeoperation.js +++ b/src/model/operation/attributeoperation.js @@ -107,6 +107,17 @@ export default class AttributeOperation extends Operation { return new AttributeOperation( this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1 ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.range = this.range.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/detachoperation.js b/src/model/operation/detachoperation.js index 5441991fa..6edc3609e 100644 --- a/src/model/operation/detachoperation.js +++ b/src/model/operation/detachoperation.js @@ -53,6 +53,17 @@ export default class DetachOperation extends Operation { return 'detach'; } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.sourcePosition = this.sourcePosition.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/insertoperation.js b/src/model/operation/insertoperation.js index a67577758..33c539b06 100644 --- a/src/model/operation/insertoperation.js +++ b/src/model/operation/insertoperation.js @@ -128,6 +128,18 @@ export default class InsertOperation extends Operation { _insert( this.position, originalNodes ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.position = this.position.toJSON(); + json.nodes = this.nodes.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/markeroperation.js b/src/model/operation/markeroperation.js index f00ab7cfb..27e8978d0 100644 --- a/src/model/operation/markeroperation.js +++ b/src/model/operation/markeroperation.js @@ -109,6 +109,14 @@ export default class MarkerOperation extends Operation { toJSON() { const json = super.toJSON(); + if ( this.oldRange ) { + json.oldRange = this.oldRange.toJSON(); + } + + if ( this.newRange ) { + json.newRange = this.newRange.toJSON(); + } + delete json._markers; return json; diff --git a/src/model/operation/mergeoperation.js b/src/model/operation/mergeoperation.js index a8c0a25be..edf6edb52 100644 --- a/src/model/operation/mergeoperation.js +++ b/src/model/operation/mergeoperation.js @@ -142,6 +142,19 @@ export default class MergeOperation extends Operation { _move( Range.createOn( mergedElement ), this.graveyardPosition ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.sourcePosition = json.sourcePosition.toJSON(); + json.targetPosition = json.targetPosition.toJSON(); + json.graveyardPosition = json.graveyardPosition.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/moveoperation.js b/src/model/operation/moveoperation.js index 3672cee28..eb1eaa683 100644 --- a/src/model/operation/moveoperation.js +++ b/src/model/operation/moveoperation.js @@ -169,6 +169,18 @@ export default class MoveOperation extends Operation { _move( Range.createFromPositionAndShift( this.sourcePosition, this.howMany ), this.targetPosition ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.sourcePosition = this.sourcePosition.toJSON(); + json.targetPosition = this.targetPosition.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/operation.js b/src/model/operation/operation.js index 9ad9e58fc..d1eb817a6 100644 --- a/src/model/operation/operation.js +++ b/src/model/operation/operation.js @@ -7,8 +7,6 @@ * @module engine/model/operation/operation */ -import clone from '@ckeditor/ckeditor5-utils/src/lib/lodash/clone'; - /** * Abstract base operation class. * @@ -94,7 +92,9 @@ export default class Operation { * @returns {Object} Clone of this object with the operation property replaced with string. */ toJSON() { - const json = clone( this, true ); + // This method creates only a shallow copy, all nested objects should be defined separately. + // See https://github.com/ckeditor/ckeditor5-engine/issues/1477. + const json = Object.assign( {}, this ); json.__className = this.constructor.className; diff --git a/src/model/operation/renameoperation.js b/src/model/operation/renameoperation.js index 565312993..7ce8ab4f0 100644 --- a/src/model/operation/renameoperation.js +++ b/src/model/operation/renameoperation.js @@ -116,6 +116,17 @@ export default class RenameOperation extends Operation { element.name = this.newName; } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.position = this.position.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/rootattributeoperation.js b/src/model/operation/rootattributeoperation.js index 6357cb82d..068901cac 100644 --- a/src/model/operation/rootattributeoperation.js +++ b/src/model/operation/rootattributeoperation.js @@ -162,6 +162,17 @@ export default class RootAttributeOperation extends Operation { } } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.root = this.root.toJSON(); + + return json; + } + /** * @inheritDoc */ @@ -186,7 +197,7 @@ export default class RootAttributeOperation extends Operation { */ throw new CKEditorError( 'rootattribute-operation-fromjson-no-root: Cannot create RootAttributeOperation. Root with specified name does not exist.', - { rootName: json } + { rootName: json.root } ); } diff --git a/src/model/operation/splitoperation.js b/src/model/operation/splitoperation.js index 0b00419d5..3b00aa662 100644 --- a/src/model/operation/splitoperation.js +++ b/src/model/operation/splitoperation.js @@ -152,6 +152,21 @@ export default class SplitOperation extends Operation { _move( sourceRange, this.moveTargetPosition ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.position = this.position.toJSON(); + + if ( this.graveyardPosition ) { + json.graveyardPosition = this.graveyardPosition.toJSON(); + } + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/unwrapoperation.js b/src/model/operation/unwrapoperation.js index 72a8f00db..76e4ae420 100644 --- a/src/model/operation/unwrapoperation.js +++ b/src/model/operation/unwrapoperation.js @@ -130,6 +130,18 @@ export default class UnwrapOperation extends Operation { _move( Range.createOn( elementToUnwrap ), this.graveyardPosition ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.position = this.position.toJSON(); + json.graveyardPosition = this.graveyardPosition.toJSON(); + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/operation/wrapoperation.js b/src/model/operation/wrapoperation.js index 5de2c6a68..253e3d962 100644 --- a/src/model/operation/wrapoperation.js +++ b/src/model/operation/wrapoperation.js @@ -156,6 +156,21 @@ export default class WrapOperation extends Operation { _move( wrappedRange, targetPosition ); } + /** + * @inheritDoc + */ + toJSON() { + const json = super.toJSON(); + + json.position = this.position.toJSON(); + + if ( json.graveyardPosition ) { + json.graveyardPosition = this.graveyardPosition.toJSON(); + } + + return json; + } + /** * @inheritDoc */ diff --git a/src/model/position.js b/src/model/position.js index 7b3cfa5a4..2c8065726 100644 --- a/src/model/position.js +++ b/src/model/position.js @@ -774,6 +774,17 @@ export default class Position { return combined; } + /** + * @inheritDoc + */ + toJSON() { + return { + root: this.root.toJSON(), + path: Array.from( this.path ), + stickiness: this.stickiness + }; + } + /** * Creates position at the given location. The location can be specified as: * @@ -899,7 +910,7 @@ export default class Position { */ static fromJSON( json, doc ) { if ( json.root === '$graveyard' ) { - const pos = new Position( doc.graveyard, json.path ); + const pos = new Position( doc.graveyard, Array.from( json.path ) ); pos.stickiness = json.stickiness; return pos; @@ -918,7 +929,7 @@ export default class Position { ); } - const pos = new Position( doc.getRoot( json.root ), json.path ); + const pos = new Position( doc.getRoot( json.root ), Array.from( json.path ) ); pos.stickiness = json.stickiness; return pos; diff --git a/src/model/range.js b/src/model/range.js index 4dc795e90..7f71402cd 100644 --- a/src/model/range.js +++ b/src/model/range.js @@ -469,6 +469,18 @@ export default class Range { return this.start.getCommonAncestor( this.end ); } + /** + * Converts `Range` to plain object and returns it. + * + * @returns {Object} `Node` converted to plain object. + */ + toJSON() { + return { + start: this.start.toJSON(), + end: this.end.toJSON() + }; + } + _getTransformedByInsertOperation( operation, spread = false ) { return this._getTransformedByInsertion( operation.position, operation.howMany, spread ); } diff --git a/tests/dev-utils/enableenginedebug.js b/tests/dev-utils/enableenginedebug.js index 4b586ac48..4120914e5 100644 --- a/tests/dev-utils/enableenginedebug.js +++ b/tests/dev-utils/enableenginedebug.js @@ -646,7 +646,7 @@ describe( 'debug tools', () => { const stringifiedOperations = model.getAppliedOperations(); - expect( stringifiedOperations ).to.equal( JSON.stringify( insert.toJSON() ) ); + expect( stringifiedOperations ).to.equal( JSON.stringify( insert ) ); } ); it( 'createReplayer()', () => { diff --git a/tests/model/_utils/utils.js b/tests/model/_utils/utils.js index 41568a2a6..b2f97571d 100644 --- a/tests/model/_utils/utils.js +++ b/tests/model/_utils/utils.js @@ -36,15 +36,6 @@ export function getNodesAndText( range ) { return txt; } -/** - * Returns object JSON representation. It passes an object by JSON.stringify and JSON.parse functions. - * - * @param {Object|Array} object - */ -export function jsonParseStringify( object ) { - return JSON.parse( JSON.stringify( object ) ); -} - /** * Returns a {@link engine.model.Node} or if it starts at given offset, or {@link engine.model.TextProxy} with one * character, if given offset is occupied by a {@link engine.model.Text}. diff --git a/tests/model/document.js b/tests/model/document.js index 11815c1a5..38cf407dd 100644 --- a/tests/model/document.js +++ b/tests/model/document.js @@ -12,7 +12,6 @@ import Range from '../../src/model/range'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import count from '@ckeditor/ckeditor5-utils/src/count'; -import { jsonParseStringify } from './_utils/utils'; describe( 'Document', () => { let model, doc; @@ -500,7 +499,7 @@ describe( 'Document', () => { } ); it( 'should be correctly converted to json', () => { - const serialized = jsonParseStringify( doc ); + const serialized = doc.toJSON(); expect( serialized.selection ).to.equal( '[engine.model.DocumentSelection]' ); expect( serialized.model ).to.equal( '[engine.model.Model]' ); diff --git a/tests/model/documentfragment.js b/tests/model/documentfragment.js index b44bd58d1..f64db3fcf 100644 --- a/tests/model/documentfragment.js +++ b/tests/model/documentfragment.js @@ -7,7 +7,6 @@ import Element from '../../src/model/element'; import Text from '../../src/model/text'; import TextProxy from '../../src/model/textproxy'; import DocumentFragment from '../../src/model/documentfragment'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; describe( 'DocumentFragment', () => { @@ -263,7 +262,7 @@ describe( 'DocumentFragment', () => { it( 'should serialize empty document fragment', () => { const frag = new DocumentFragment(); - expect( jsonParseStringify( frag ) ).to.deep.equal( [] ); + expect( frag.toJSON() ).to.deep.equal( [] ); } ); it( 'should serialize document fragment with children', () => { @@ -274,7 +273,7 @@ describe( 'DocumentFragment', () => { const frag = new DocumentFragment( [ one, two, three ] ); - expect( jsonParseStringify( frag ) ).to.deep.equal( [ + expect( frag.toJSON() ).to.deep.equal( [ { name: 'one' }, { name: 'two', @@ -293,7 +292,7 @@ describe( 'DocumentFragment', () => { it( 'should create document fragment without children', () => { const frag = new DocumentFragment(); - const serialized = jsonParseStringify( frag ); + const serialized = frag.toJSON(); const deserialized = DocumentFragment.fromJSON( serialized ); expect( deserialized.isEmpty ).to.be.true; @@ -304,7 +303,7 @@ describe( 'DocumentFragment', () => { const foo = new Text( 'foo' ); const frag = new DocumentFragment( [ p, foo ] ); - const serialized = jsonParseStringify( frag ); + const serialized = frag.toJSON(); const deserialized = DocumentFragment.fromJSON( serialized ); expect( deserialized.childCount ).to.equal( 2 ); diff --git a/tests/model/element.js b/tests/model/element.js index cdb03e123..85fa4fee1 100644 --- a/tests/model/element.js +++ b/tests/model/element.js @@ -7,7 +7,6 @@ import Node from '../../src/model/node'; import Element from '../../src/model/element'; import Text from '../../src/model/text'; import TextProxy from '../../src/model/textproxy'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; import count from '@ckeditor/ckeditor5-utils/src/count'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; @@ -320,14 +319,17 @@ describe( 'Element', () => { it( 'should serialize empty element', () => { const element = new Element( 'one' ); - expect( jsonParseStringify( element ) ).to.deep.equal( { name: 'one' } ); + expect( element.toJSON() ).to.deep.equal( { name: 'one' } ); } ); it( 'should serialize element with attributes', () => { const element = new Element( 'one', { foo: true, bar: false } ); - expect( jsonParseStringify( element ) ).to.deep.equal( { - attributes: [ [ 'foo', true ], [ 'bar', false ] ], + expect( element.toJSON() ).to.deep.equal( { + attributes: { + foo: true, + bar: false + }, name: 'one' } ); } ); @@ -340,7 +342,7 @@ describe( 'Element', () => { const node = new Element( null, null, [ one, two, three ] ); - expect( jsonParseStringify( node ) ).to.deep.equal( { + expect( node.toJSON() ).to.deep.equal( { children: [ { name: 'one' }, { @@ -362,7 +364,7 @@ describe( 'Element', () => { it( 'should create element without attributes', () => { const el = new Element( 'el' ); - const serialized = jsonParseStringify( el ); + const serialized = el.toJSON(); const deserialized = Element.fromJSON( serialized ); @@ -374,7 +376,7 @@ describe( 'Element', () => { it( 'should create element with attributes', () => { const el = new Element( 'el', { foo: true } ); - const serialized = jsonParseStringify( el ); + const serialized = el.toJSON(); const deserialized = Element.fromJSON( serialized ); @@ -390,7 +392,7 @@ describe( 'Element', () => { const text = new Text( 'foo' ); const el = new Element( 'el', null, [ p, text ] ); - const serialized = jsonParseStringify( el ); + const serialized = el.toJSON(); const deserialized = Element.fromJSON( serialized ); diff --git a/tests/model/nodelist.js b/tests/model/nodelist.js index 5fb5114ff..a3b02affe 100644 --- a/tests/model/nodelist.js +++ b/tests/model/nodelist.js @@ -6,7 +6,6 @@ import NodeList from '../../src/model/nodelist'; import Element from '../../src/model/element'; import Text from '../../src/model/text'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; describe( 'NodeList', () => { @@ -195,11 +194,11 @@ describe( 'NodeList', () => { describe( 'toJSON', () => { it( 'should serialize empty node list', () => { - expect( jsonParseStringify( new NodeList() ) ).to.deep.equal( [] ); + expect( ( new NodeList() ).toJSON() ).to.deep.equal( [] ); } ); it( 'should serialize node list with nodes', () => { - expect( jsonParseStringify( nodes ) ).to.deep.equal( [ + expect( nodes.toJSON() ).to.deep.equal( [ { name: 'p' }, { data: 'foo' }, { name: 'image' } diff --git a/tests/model/operation/attributeoperation.js b/tests/model/operation/attributeoperation.js index 7e349c82f..5b950ba0a 100644 --- a/tests/model/operation/attributeoperation.js +++ b/tests/model/operation/attributeoperation.js @@ -10,7 +10,6 @@ import Position from '../../../src/model/position'; import Range from '../../../src/model/range'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import count from '@ckeditor/ckeditor5-utils/src/count'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'AttributeOperation', () => { let model, doc, root; @@ -377,16 +376,17 @@ describe( 'AttributeOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized.__className ).to.equal( 'engine.model.operation.AttributeOperation' ); + expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.AttributeOperation', baseVersion: 0, key: 'key', newValue: 'newValue', oldValue: null, - range: jsonParseStringify( range ) + range: range.toJSON() } ); } ); } ); @@ -402,7 +402,7 @@ describe( 'AttributeOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = AttributeOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/detachoperation.js b/tests/model/operation/detachoperation.js index d75da0f60..26eddae28 100644 --- a/tests/model/operation/detachoperation.js +++ b/tests/model/operation/detachoperation.js @@ -5,7 +5,6 @@ import Model from '../../../src/model/model'; import DetachOperation from '../../../src/model/operation/detachoperation'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import Position from '../../../src/model/position'; import DocumentFragment from '../../../src/model/documentfragment'; @@ -61,12 +60,12 @@ describe( 'DetachOperation', () => { const position = Position.createBefore( element ); const op = new DetachOperation( position, 1 ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.DetachOperation', baseVersion: null, - sourcePosition: jsonParseStringify( position ), + sourcePosition: position.toJSON(), howMany: 1 } ); } ); diff --git a/tests/model/operation/insertoperation.js b/tests/model/operation/insertoperation.js index 6f59cf3dc..837c19474 100644 --- a/tests/model/operation/insertoperation.js +++ b/tests/model/operation/insertoperation.js @@ -11,7 +11,6 @@ import RemoveOperation from '../../../src/model/operation/removeoperation'; import Position from '../../../src/model/position'; import Text from '../../../src/model/text'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'InsertOperation', () => { let model, doc, root; @@ -223,13 +222,13 @@ describe( 'InsertOperation', () => { const op = new InsertOperation( position, new Text( 'x' ), doc.version ); op.shouldReceiveAttributes = true; - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.InsertOperation', baseVersion: 0, - nodes: jsonParseStringify( new NodeList( [ new Text( 'x' ) ] ) ), - position: jsonParseStringify( position ), + nodes: ( new NodeList( [ new Text( 'x' ) ] ) ).toJSON(), + position: position.toJSON(), shouldReceiveAttributes: true } ); } ); @@ -244,7 +243,7 @@ describe( 'InsertOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = InsertOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/markeroperation.js b/tests/model/operation/markeroperation.js index ab77df59f..16b913740 100644 --- a/tests/model/operation/markeroperation.js +++ b/tests/model/operation/markeroperation.js @@ -7,7 +7,6 @@ import Model from '../../../src/model/model'; import Text from '../../../src/model/text'; import Range from '../../../src/model/range'; import MarkerOperation from '../../../src/model/operation/markeroperation'; -import { jsonParseStringify } from '../../model/_utils/utils'; function matchRange( range ) { return sinon.match( rangeToMatch => rangeToMatch.isEqual( range ) ); @@ -135,14 +134,14 @@ describe( 'MarkerOperation', () => { describe( 'toJSON', () => { it( 'should create proper serialized object', () => { const op = new MarkerOperation( 'name', null, range, model.markers, doc.version, true ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.MarkerOperation', baseVersion: 0, name: 'name', oldRange: null, - newRange: jsonParseStringify( range ), + newRange: range.toJSON(), affectsData: true } ); } ); @@ -152,7 +151,7 @@ describe( 'MarkerOperation', () => { it( 'should create proper MarkerOperation from json object #1', () => { const op = new MarkerOperation( 'name', null, range, model.markers, doc.version, true ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = MarkerOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); @@ -162,7 +161,7 @@ describe( 'MarkerOperation', () => { // Gotta love 100% CC. const op = new MarkerOperation( 'name', range, null, model.markers, doc.version, true ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = MarkerOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/moveoperation.js b/tests/model/operation/moveoperation.js index d2ff1edde..5b762fbc6 100644 --- a/tests/model/operation/moveoperation.js +++ b/tests/model/operation/moveoperation.js @@ -9,7 +9,6 @@ import Position from '../../../src/model/position'; import Element from '../../../src/model/element'; import Text from '../../../src/model/text'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'MoveOperation', () => { let model, doc, root; @@ -266,14 +265,14 @@ describe( 'MoveOperation', () => { const targetPosition = new Position( root, [ 1, 0 ] ); const op = new MoveOperation( sourcePosition, 1, targetPosition, doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.MoveOperation', baseVersion: 0, howMany: 1, - sourcePosition: jsonParseStringify( op.sourcePosition ), - targetPosition: jsonParseStringify( op.targetPosition ) + sourcePosition: op.sourcePosition.toJSON(), + targetPosition: op.targetPosition.toJSON() } ); } ); } ); @@ -284,7 +283,7 @@ describe( 'MoveOperation', () => { const targetPosition = new Position( root, [ 1, 0 ] ); const op = new MoveOperation( sourcePosition, 1, targetPosition, doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = MoveOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/nooperation.js b/tests/model/operation/nooperation.js index 18d3ebe9b..17e74aeca 100644 --- a/tests/model/operation/nooperation.js +++ b/tests/model/operation/nooperation.js @@ -5,7 +5,6 @@ import Model from '../../../src/model/model'; import NoOperation from '../../../src/model/operation/nooperation'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'NoOperation', () => { let model, noop, doc; @@ -36,7 +35,7 @@ describe( 'NoOperation', () => { describe( 'toJSON', () => { it( 'should create proper json object', () => { - const serialized = jsonParseStringify( noop ); + const serialized = noop.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.NoOperation', @@ -47,7 +46,7 @@ describe( 'NoOperation', () => { describe( 'fromJSON', () => { it( 'should create proper NoOperation from json object', () => { - const serialized = jsonParseStringify( noop ); + const serialized = noop.toJSON(); const deserialized = NoOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( noop ); diff --git a/tests/model/operation/operation.js b/tests/model/operation/operation.js index 018fff35d..cc9bb2d69 100644 --- a/tests/model/operation/operation.js +++ b/tests/model/operation/operation.js @@ -5,7 +5,6 @@ import Batch from '../../../src/model/batch'; import Operation from '../../../src/model/operation/operation'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'Operation', () => { it( 'should save its base version', () => { @@ -32,7 +31,7 @@ describe( 'Operation', () => { it( 'should create proper json object #1', () => { const op = new Operation( 4 ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.Operation', @@ -45,7 +44,7 @@ describe( 'Operation', () => { const batch = new Batch(); batch.addOperation( op ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.Operation', @@ -58,7 +57,7 @@ describe( 'Operation', () => { it( 'should create proper Operation from json object', () => { const op = new Operation( 4 ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = Operation.fromJSON( serialized ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/reinsertoperation.js b/tests/model/operation/reinsertoperation.js index da927dfc2..cdd3ed2b9 100644 --- a/tests/model/operation/reinsertoperation.js +++ b/tests/model/operation/reinsertoperation.js @@ -12,7 +12,6 @@ import DocumentFragment from '../../../src/model/documentfragment'; import Element from '../../../src/model/element'; import Text from '../../../src/model/text'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'ReinsertOperation', () => { let model, doc, root, graveyard, operation, graveyardPosition, rootPosition; @@ -134,21 +133,21 @@ describe( 'ReinsertOperation', () => { describe( 'toJSON', () => { it( 'should create proper json object', () => { - const serialized = jsonParseStringify( operation ); + const serialized = operation.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.ReinsertOperation', baseVersion: 0, howMany: 2, - sourcePosition: jsonParseStringify( operation.sourcePosition ), - targetPosition: jsonParseStringify( operation.targetPosition ) + sourcePosition: operation.sourcePosition.toJSON(), + targetPosition: operation.targetPosition.toJSON() } ); } ); } ); describe( 'fromJSON', () => { it( 'should create proper ReinsertOperation from json object', () => { - const serialized = jsonParseStringify( operation ); + const serialized = operation.toJSON(); const deserialized = ReinsertOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( operation ); diff --git a/tests/model/operation/removeoperation.js b/tests/model/operation/removeoperation.js index da9bf72b1..52de32388 100644 --- a/tests/model/operation/removeoperation.js +++ b/tests/model/operation/removeoperation.js @@ -12,7 +12,6 @@ import DocumentFragment from '../../../src/model/documentfragment'; import Element from '../../../src/model/element'; import Text from '../../../src/model/text'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'RemoveOperation', () => { let model, doc, root, graveyard; @@ -161,14 +160,14 @@ describe( 'RemoveOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.RemoveOperation', baseVersion: 0, howMany: 2, - sourcePosition: jsonParseStringify( op.sourcePosition ), - targetPosition: jsonParseStringify( op.targetPosition ) + sourcePosition: op.sourcePosition.toJSON(), + targetPosition: op.targetPosition.toJSON() } ); } ); } ); @@ -182,7 +181,7 @@ describe( 'RemoveOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = RemoveOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/renameoperation.js b/tests/model/operation/renameoperation.js index 5e266d0b6..8416a303a 100644 --- a/tests/model/operation/renameoperation.js +++ b/tests/model/operation/renameoperation.js @@ -8,7 +8,6 @@ import Element from '../../../src/model/element'; import RenameOperation from '../../../src/model/operation/renameoperation'; import Position from '../../../src/model/position'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'RenameOperation', () => { const oldName = 'oldName'; @@ -106,12 +105,12 @@ describe( 'RenameOperation', () => { describe( 'toJSON', () => { it( 'should create proper serialized object', () => { const op = new RenameOperation( Position.createAt( root, 'end' ), oldName, newName, doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized ).to.deep.equal( { __className: 'engine.model.operation.RenameOperation', baseVersion: 0, - position: jsonParseStringify( op.position ), + position: op.position.toJSON(), newName: 'newName', oldName: 'oldName' } ); @@ -122,7 +121,7 @@ describe( 'RenameOperation', () => { it( 'should create proper AttributeOperation from json object', () => { const op = new RenameOperation( Position.createAt( root, 'end' ), oldName, newName, doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = RenameOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); diff --git a/tests/model/operation/rootattributeoperation.js b/tests/model/operation/rootattributeoperation.js index 024e00a3a..221e19ab7 100644 --- a/tests/model/operation/rootattributeoperation.js +++ b/tests/model/operation/rootattributeoperation.js @@ -8,7 +8,6 @@ import DocumentFragment from '../../../src/model/documentfragment'; import Element from '../../../src/model/element'; import RootAttributeOperation from '../../../src/model/operation/rootattributeoperation'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../../tests/model/_utils/utils'; describe( 'RootAttributeOperation', () => { let model, doc, root; @@ -268,7 +267,7 @@ describe( 'RootAttributeOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); expect( serialized.__className ).to.equal( 'engine.model.operation.RootAttributeOperation' ); expect( serialized ).to.deep.equal( { @@ -286,7 +285,7 @@ describe( 'RootAttributeOperation', () => { it( 'should create proper RootAttributeOperation from json object', () => { const op = new RootAttributeOperation( root, 'key', null, 'newValue', doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); const deserialized = RootAttributeOperation.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( op ); @@ -301,7 +300,8 @@ describe( 'RootAttributeOperation', () => { doc.version ); - const serialized = jsonParseStringify( op ); + const serialized = op.toJSON(); + serialized.root = 'no-root'; expect( () => { diff --git a/tests/model/position.js b/tests/model/position.js index be44ec22c..0f03e85be 100644 --- a/tests/model/position.js +++ b/tests/model/position.js @@ -11,7 +11,6 @@ import TextProxy from '../../src/model/textproxy'; import Position from '../../src/model/position'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; describe( 'Position', () => { let doc, root, otherRoot, p, ul, li1, li2, f, o, z, b, a, r, foz, bar; @@ -805,7 +804,7 @@ describe( 'Position', () => { it( 'should serialize position', () => { const position = new Position( root, [ 0 ] ); - const serialized = jsonParseStringify( position ); + const serialized = position.toJSON(); expect( serialized ).to.deep.equal( { root: 'main', path: [ 0 ], stickiness: 'toNone' } ); } ); @@ -814,7 +813,7 @@ describe( 'Position', () => { const position = new Position( doc.graveyard, [ 0 ] ); position.stickiness = 'toPrevious'; - const serialized = jsonParseStringify( position ); + const serialized = position.toJSON(); expect( serialized ).to.deep.equal( { root: '$graveyard', path: [ 0 ], stickiness: 'toPrevious' } ); } ); diff --git a/tests/model/range.js b/tests/model/range.js index feea61f39..395788cf5 100644 --- a/tests/model/range.js +++ b/tests/model/range.js @@ -19,7 +19,6 @@ import SplitOperation from '../../src/model/operation/splitoperation'; import WrapOperation from '../../src/model/operation/wrapoperation'; import UnwrapOperation from '../../src/model/operation/unwrapoperation'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; describe( 'Range', () => { let doc, range, start, end, root, otherRoot, gy; @@ -1266,9 +1265,22 @@ describe( 'Range', () => { } ); } ); + describe( 'toJSON()', () => { + it( 'should serialize range', () => { + const range = new Range( new Position( root, [ 1 ] ), new Position( root, [ 3 ] ) ); + + const serialized = range.toJSON(); + + expect( serialized ).to.deep.equal( { + start: { root: 'main', path: [ 1 ], stickiness: 'toNext' }, + end: { root: 'main', path: [ 3 ], stickiness: 'toPrevious' } + } ); + } ); + } ); + describe( 'fromJSON()', () => { it( 'should create range from given JSON object', () => { - const serialized = jsonParseStringify( range ); + const serialized = range.toJSON(); const deserialized = Range.fromJSON( serialized, doc ); expect( deserialized ).to.deep.equal( range ); diff --git a/tests/model/text.js b/tests/model/text.js index 9d8a97c95..95090e5d3 100644 --- a/tests/model/text.js +++ b/tests/model/text.js @@ -5,7 +5,6 @@ import Text from '../../src/model/text'; import Node from '../../src/model/node'; -import { jsonParseStringify } from '../../tests/model/_utils/utils'; describe( 'Text', () => { describe( 'constructor()', () => { @@ -67,8 +66,8 @@ describe( 'Text', () => { it( 'should serialize text node', () => { const text = new Text( 'foo', { bold: true } ); - expect( jsonParseStringify( text ) ).to.deep.equal( { - attributes: [ [ 'bold', true ] ], + expect( text.toJSON() ).to.deep.equal( { + attributes: { bold: true }, data: 'foo' } ); } ); @@ -78,7 +77,7 @@ describe( 'Text', () => { it( 'should create text node', () => { const text = new Text( 'foo', { bold: true } ); - const serialized = jsonParseStringify( text ); + const serialized = text.toJSON(); const deserialized = Text.fromJSON( serialized ); expect( deserialized.data ).to.equal( 'foo' ); @@ -87,7 +86,7 @@ describe( 'Text', () => { it( 'should support unicode', () => { const textQ = new Text( 'நி' ); - const json = jsonParseStringify( textQ ); + const json = textQ.toJSON(); expect( json ).to.deep.equal( { data: 'நி' diff --git a/tests/model/utils-tests/utils.js b/tests/model/utils-tests/utils.js index af79bd88e..89a7a2d74 100644 --- a/tests/model/utils-tests/utils.js +++ b/tests/model/utils-tests/utils.js @@ -5,7 +5,6 @@ import { getNodesAndText, - jsonParseStringify, itemAt, getText, createRangeOnElementOnly @@ -37,22 +36,6 @@ describe( 'getNodesAndText', () => { } ); } ); -describe( 'jsonParseStringify', () => { - class Foo { - constructor( ra ) { - this.ra = ra; - } - } - - it( 'should return cleaned object', () => { - const foo = new Foo( { bar: 'bar' } ); - - const fooJsoned = jsonParseStringify( foo ); - expect( fooJsoned ).to.not.be.instanceOf( Foo ); - expect( fooJsoned ).to.deep.equal( { ra: { bar: 'bar' } } ); - } ); -} ); - describe( 'itemAt', () => { let foo, img, bar, element;