浏览代码

Adjusted to changes made in engine view.

Szymon Kupś 7 年之前
父节点
当前提交
b34b0342f8

+ 28 - 20
packages/ckeditor5-list/src/converters.js

@@ -14,7 +14,6 @@ import ViewContainerElement from '@ckeditor/ckeditor5-engine/src/view/containere
 import ViewPosition from '@ckeditor/ckeditor5-engine/src/view/position';
 import ViewRange from '@ckeditor/ckeditor5-engine/src/view/range';
 import ViewTreeWalker from '@ckeditor/ckeditor5-engine/src/view/treewalker';
-import viewWriter from '@ckeditor/ckeditor5-engine/src/view/writer';
 import { createViewListItemElement } from './utils';
 
 /**
@@ -44,7 +43,7 @@ export function modelViewInsertion( evt, data, consumable, conversionApi ) {
 	const modelItem = data.item;
 	const viewItem = generateLiInUl( modelItem, conversionApi.mapper );
 
-	injectViewList( modelItem, viewItem, conversionApi.mapper );
+	injectViewList( modelItem, viewItem, conversionApi );
 }
 
 /**
@@ -59,6 +58,7 @@ export function modelViewInsertion( evt, data, consumable, conversionApi ) {
 export function modelViewRemove( evt, data, conversionApi ) {
 	const viewStart = conversionApi.mapper.toViewPosition( data.position ).getLastMatchingPosition( value => !value.item.is( 'li' ) );
 	const viewItem = viewStart.nodeAfter;
+	const viewWriter = conversionApi.writer;
 
 	// 1. Break the container after and before the list item.
 	// This will create a view list with one view list item - the one to remove.
@@ -73,13 +73,13 @@ export function modelViewRemove( evt, data, conversionApi ) {
 
 	// 3. Merge the whole created by breaking and removing the list.
 	if ( viewListPrev && viewListPrev.nextSibling ) {
-		mergeViewLists( viewListPrev, viewListPrev.nextSibling );
+		mergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );
 	}
 
 	// 4. Bring back nested list that was in the removed <li>.
 	const modelItem = conversionApi.mapper.toModelElement( viewItem );
 
-	hoistNestedLists( modelItem.getAttribute( 'indent' ) + 1, data.position, removeRange.start, viewItem, conversionApi.mapper );
+	hoistNestedLists( modelItem.getAttribute( 'indent' ) + 1, data.position, removeRange.start, viewItem, conversionApi );
 
 	// 5. Unbind removed view item and all children.
 	for ( const child of ViewRange.createIn( removed ).getItems() ) {
@@ -107,6 +107,7 @@ export function modelViewChangeType( evt, data, consumable, conversionApi ) {
 	}
 
 	const viewItem = conversionApi.mapper.toViewElement( data.item );
+	const viewWriter = conversionApi.writer;
 
 	// 1. Break the container after and before the list item.
 	// This will create a view list with one view list item -- the one that changed type.
@@ -120,8 +121,8 @@ export function modelViewChangeType( evt, data, consumable, conversionApi ) {
 	viewList = viewWriter.rename( viewList, listName );
 
 	// 3. Merge the changed view list with other lists, if possible.
-	mergeViewLists( viewList, viewList.nextSibling );
-	mergeViewLists( viewList.previousSibling, viewList );
+	mergeViewLists( viewWriter, viewList, viewList.nextSibling );
+	mergeViewLists( viewWriter, viewList.previousSibling, viewList );
 
 	// 4. Consumable insertion of children inside the item. They are already handled by re-building the item in view.
 	for ( const child of data.item.getChildren() ) {
@@ -144,6 +145,7 @@ export function modelViewChangeIndent( evt, data, consumable, conversionApi ) {
 	}
 
 	const viewItem = conversionApi.mapper.toViewElement( data.item );
+	const viewWriter = conversionApi.writer;
 
 	// 1. Break the container after and before the list item.
 	// This will create a view list with one view list item -- the one that changed type.
@@ -160,7 +162,7 @@ export function modelViewChangeIndent( evt, data, consumable, conversionApi ) {
 	let removePosition;
 
 	if ( viewListPrev && viewListPrev.nextSibling ) {
-		removePosition = mergeViewLists( viewListPrev, viewListPrev.nextSibling );
+		removePosition = mergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );
 	}
 
 	if ( !removePosition ) {
@@ -168,10 +170,10 @@ export function modelViewChangeIndent( evt, data, consumable, conversionApi ) {
 	}
 
 	// 3. Bring back nested list that was in the removed <li>.
-	hoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi.mapper );
+	hoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi );
 
 	// 4. Inject view list like it is newly inserted.
-	injectViewList( data.item, viewItem, conversionApi.mapper );
+	injectViewList( data.item, viewItem, conversionApi );
 
 	// 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.
 	for ( const child of data.item.getChildren() ) {
@@ -208,6 +210,7 @@ export function modelViewSplitOnInsert( evt, data, consumable, conversionApi ) {
 	if ( data.item.name != 'listItem' ) {
 		let viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
 
+		const viewWriter = conversionApi.writer;
 		const lists = [];
 
 		// Break multiple ULs/OLs if there are.
@@ -286,7 +289,7 @@ export function modelViewSplitOnInsert( evt, data, consumable, conversionApi ) {
 
 				// Don't merge first list! We want a split in that place (this is why this converter is introduced).
 				if ( i > 0 ) {
-					const mergePos = mergeViewLists( previousList, previousList.nextSibling );
+					const mergePos = mergeViewLists( viewWriter, previousList, previousList.nextSibling );
 
 					// If `mergePos` is in `previousList` it means that the lists got merged.
 					// In this case, we need to fix insert position.
@@ -297,7 +300,7 @@ export function modelViewSplitOnInsert( evt, data, consumable, conversionApi ) {
 			}
 
 			// Merge last inserted list with element after it.
-			mergeViewLists( viewPosition.nodeBefore, viewPosition.nodeAfter );
+			mergeViewLists( viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter );
 		}
 	}
 }
@@ -333,7 +336,7 @@ export function modelViewMergeAfter( evt, data, conversionApi ) {
 	// Merge lists if something (remove, move) was done from inside of list.
 	// Merging will be done only if both items are view lists of the same type.
 	// The check is done inside the helper function.
-	mergeViewLists( viewItemPrev, viewItemNext );
+	mergeViewLists( conversionApi.writer, viewItemPrev, viewItemNext );
 }
 
 /**
@@ -829,7 +832,7 @@ function getSiblingListItem( modelItemOrPosition, options ) {
 
 // Helper function that takes two parameters, that are expected to be view list elements, and merges them.
 // The merge happen only if both parameters are UL or OL elements.
-function mergeViewLists( firstList, secondList ) {
+function mergeViewLists( viewWriter, firstList, secondList ) {
 	if ( firstList && secondList && ( firstList.name == 'ul' || firstList.name == 'ol' ) && firstList.name == secondList.name ) {
 		return viewWriter.mergeContainers( ViewPosition.createAfter( firstList ) );
 	}
@@ -841,8 +844,10 @@ function mergeViewLists( firstList, secondList ) {
 // that is not added to the view and is inside a view list element (`ul` or `ol`) and is that's list only child.
 // The list is inserted at correct position (element breaking may be needed) and then merged with it's siblings.
 // See comments below to better understand the algorithm.
-function injectViewList( modelItem, injectedItem, mapper ) {
+function injectViewList( modelItem, injectedItem, conversionApi ) {
 	const injectedList = injectedItem.parent;
+	const mapper = conversionApi.mapper;
+	const viewWriter = conversionApi.writer;
 
 	// Position where view list will be inserted.
 	let insertPosition = mapper.toViewPosition( ModelPosition.createBefore( modelItem ) );
@@ -894,7 +899,7 @@ function injectViewList( modelItem, injectedItem, mapper ) {
 				const viewList = value.item.parent;
 
 				const targetPosition = ViewPosition.createAt( injectedItem, 'end' );
-				mergeViewLists( targetPosition.nodeBefore, targetPosition.nodeAfter );
+				mergeViewLists( viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter );
 				viewWriter.move( ViewRange.createOn( viewList ), targetPosition );
 
 				walker.position = breakPosition;
@@ -924,13 +929,13 @@ function injectViewList( modelItem, injectedItem, mapper ) {
 	}
 
 	// Merge inserted view list with its possible neighbour lists.
-	mergeViewLists( injectedList, injectedList.nextSibling );
-	mergeViewLists( injectedList.previousSibling, injectedList );
+	mergeViewLists( viewWriter, injectedList, injectedList.nextSibling );
+	mergeViewLists( viewWriter, injectedList.previousSibling, injectedList );
 }
 
 // Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according
 // to other given parameters.
-function hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, mapper ) {
+function hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi ) {
 	// Find correct previous model list item element.
 	// The element has to have either same or smaller indent than given reference indent.
 	// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).
@@ -941,6 +946,9 @@ function hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStart
 		indent: nextIndent
 	} );
 
+	const mapper = conversionApi.mapper;
+	const viewWriter = conversionApi.writer;
+
 	// Indent of found element or `null` if the element has not been found.
 	const prevIndent = prevModelItem ? prevModelItem.getAttribute( 'indent' ) : null;
 
@@ -1015,8 +1023,8 @@ function hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStart
 		if ( child.is( 'ul' ) || child.is( 'ol' ) ) {
 			insertPosition = viewWriter.move( ViewRange.createOn( child ), insertPosition ).end;
 
-			mergeViewLists( child, child.nextSibling );
-			mergeViewLists( child.previousSibling, child );
+			mergeViewLists( viewWriter, child, child.nextSibling );
+			mergeViewLists( viewWriter, child.previousSibling, child );
 		}
 	}
 }

+ 4 - 2
packages/ckeditor5-list/src/list.js

@@ -47,9 +47,11 @@ export default class List extends Plugin {
 		this._addButton( 'numberedList', t( 'Numbered List' ), numberedListIcon );
 		this._addButton( 'bulletedList', t( 'Bulleted List' ), bulletedListIcon );
 
+		const viewDocument = this.editor.editing.view.document;
+
 		// Overwrite default Enter key behavior.
 		// If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.
-		this.listenTo( this.editor.editing.view, 'enter', ( evt, data ) => {
+		this.listenTo( viewDocument, 'enter', ( evt, data ) => {
 			const doc = this.editor.model.document;
 			const positionParent = doc.selection.getLastPosition().parent;
 
@@ -63,7 +65,7 @@ export default class List extends Plugin {
 
 		// Overwrite default Backspace key behavior.
 		// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83
-		this.listenTo( this.editor.editing.view, 'delete', ( evt, data ) => {
+		this.listenTo( viewDocument, 'delete', ( evt, data ) => {
 			// Check conditions from those that require less computations like those immediately available.
 			if ( data.direction !== 'backward' ) {
 				return;

+ 6 - 6
packages/ckeditor5-list/tests/list.js

@@ -98,7 +98,7 @@ describe( 'List', () => {
 
 			setData( model, '<listItem type="bulleted" indent="0">[]</listItem>' );
 
-			editor.editing.view.fire( 'enter', domEvtDataStub );
+			editor.editing.view.document.fire( 'enter', domEvtDataStub );
 
 			expect( editor.execute.calledOnce ).to.be.true;
 			expect( editor.execute.calledWithExactly( 'outdentList' ) );
@@ -111,7 +111,7 @@ describe( 'List', () => {
 
 			setData( model, '<listItem type="bulleted" indent="0">foo[]</listItem>' );
 
-			editor.editing.view.fire( 'enter', domEvtDataStub );
+			editor.editing.view.document.fire( 'enter', domEvtDataStub );
 
 			expect( editor.execute.called ).to.be.false;
 		} );
@@ -263,7 +263,7 @@ describe( 'List', () => {
 				'<listItem type="bulleted" indent="0">[]bar</listItem>'
 			);
 
-			editor.editing.view.fire( 'keydown', domEvtDataStub );
+			editor.editing.view.document.fire( 'keydown', domEvtDataStub );
 
 			expect( editor.execute.calledOnce ).to.be.true;
 			expect( editor.execute.calledWithExactly( 'indentList' ) ).to.be.true;
@@ -280,7 +280,7 @@ describe( 'List', () => {
 				'<listItem type="bulleted" indent="1">[]bar</listItem>'
 			);
 
-			editor.editing.view.fire( 'keydown', domEvtDataStub );
+			editor.editing.view.document.fire( 'keydown', domEvtDataStub );
 
 			expect( editor.execute.calledOnce ).to.be.true;
 			expect( editor.execute.calledWithExactly( 'outdentList' ) ).to.be.true;
@@ -291,7 +291,7 @@ describe( 'List', () => {
 		it( 'should not indent if command is disabled', () => {
 			setData( model, '<listItem type="bulleted" indent="0">[]foo</listItem>' );
 
-			editor.editing.view.fire( 'keydown', domEvtDataStub );
+			editor.editing.view.document.fire( 'keydown', domEvtDataStub );
 
 			expect( editor.execute.called ).to.be.false;
 			sinon.assert.notCalled( domEvtDataStub.preventDefault );
@@ -307,7 +307,7 @@ describe( 'List', () => {
 				'<listItem type="bulleted" indent="0">[]bar</listItem>'
 			);
 
-			editor.editing.view.fire( 'keydown', domEvtDataStub );
+			editor.editing.view.document.fire( 'keydown', domEvtDataStub );
 
 			expect( editor.execute.called ).to.be.false;
 			sinon.assert.notCalled( domEvtDataStub.preventDefault );

+ 8 - 7
packages/ckeditor5-list/tests/listengine.js

@@ -27,7 +27,7 @@ import { getData as getViewData, parse as parseView } from '@ckeditor/ckeditor5-
 import { insertElement } from '@ckeditor/ckeditor5-engine/src/conversion/model-to-view-converters';
 
 describe( 'ListEngine', () => {
-	let editor, model, modelDoc, modelRoot, viewDoc, viewRoot;
+	let editor, model, modelDoc, modelRoot, view, viewDoc, viewRoot;
 
 	beforeEach( () => {
 		return VirtualTestEditor
@@ -41,7 +41,8 @@ describe( 'ListEngine', () => {
 				modelDoc = model.document;
 				modelRoot = modelDoc.getRoot();
 
-				viewDoc = editor.editing.view;
+				view = editor.editing.view;
+				viewDoc = view.document;
 				viewRoot = viewDoc.getRoot();
 			} );
 	} );
@@ -3596,29 +3597,29 @@ describe( 'ListEngine', () => {
 
 			actionCallback();
 
-			expect( getViewData( viewDoc, { withoutSelection: true } ) ).to.equal( output );
+			expect( getViewData( view, { withoutSelection: true } ) ).to.equal( output );
 		} );
 
 		it( testName + ' (undo integration)', () => {
 			setModelData( model, input );
 
 			const modelBefore = input;
-			const viewBefore = getViewData( viewDoc, { withoutSelection: true } );
+			const viewBefore = getViewData( view, { withoutSelection: true } );
 
 			actionCallback();
 
 			const modelAfter = getModelData( model );
-			const viewAfter = getViewData( viewDoc, { withoutSelection: true } );
+			const viewAfter = getViewData( view, { withoutSelection: true } );
 
 			editor.execute( 'undo' );
 
 			expect( getModelData( model ) ).to.equal( modelBefore );
-			expect( getViewData( viewDoc, { withoutSelection: true } ) ).to.equal( viewBefore );
+			expect( getViewData( view, { withoutSelection: true } ) ).to.equal( viewBefore );
 
 			editor.execute( 'redo' );
 
 			expect( getModelData( model ) ).to.equal( modelAfter );
-			expect( getViewData( viewDoc, { withoutSelection: true } ) ).to.equal( viewAfter );
+			expect( getViewData( view, { withoutSelection: true } ) ).to.equal( viewAfter );
 		} );
 	}
 } );