浏览代码

Handle Safari 'br' edge case.

Krzysztof Krztoń 7 年之前
父节点
当前提交
c37b34c328
共有 2 个文件被更改,包括 30 次插入4 次删除
  1. 6 4
      packages/ckeditor5-engine/src/view/renderer.js
  2. 24 0
      packages/ckeditor5-engine/tests/view/renderer.js

+ 6 - 4
packages/ckeditor5-engine/src/view/renderer.js

@@ -316,10 +316,12 @@ export default class Renderer {
 						const deleteIndex = counter.equal + counter.delete;
 						const viewChild = viewElement.getChild( insertIndex );
 
-						this.domConverter.unbindDomElement( diff.actualDomChildren[ deleteIndex ] );
-						this.domConverter.bindElements( diff.actualDomChildren[ deleteIndex ], viewChild );
-						// View element may have children which needs to be updated but are not marked, mark them to update.
-						this.markedChildren.add( viewChild );
+						if ( viewChild ) {
+							this.domConverter.unbindDomElement( diff.actualDomChildren[ deleteIndex ] );
+							this.domConverter.bindElements( diff.actualDomChildren[ deleteIndex ], viewChild );
+							// View element may have children which needs to be updated but are not marked, mark them to update.
+							this.markedChildren.add( viewChild );
+						}
 
 						remove( diff.expectedDomChildren[ insertIndex ] );
 						counter.equal++;

+ 24 - 0
packages/ckeditor5-engine/tests/view/renderer.js

@@ -2757,6 +2757,30 @@ describe( 'Renderer', () => {
 					'<blockquote>Foo Bar Baz</blockquote>' +
 					'<ul><li>Item <strong>1</strong></li><li><a href="https://ckeditor.com">Item</a> 2</li></ul>' );
 			} );
+
+			it( 'should properly handle br elements while refreshing bindings', () => {
+				const expected = `<p>Foo Bar</p><p>${ BR_FILLER( document ).outerHTML }</p>`; // eslint-disable-line new-cap
+
+				viewRoot._appendChild( parse( '<container:p>Foo Bar</container:p><container:p></container:p>' ) );
+
+				renderer.markToSync( 'children', viewRoot );
+				renderer.render();
+
+				expect( domRoot.innerHTML ).to.equal( expected );
+
+				// There is a case in Safari that during accent panel navigation on macOS our 'BR_FILLER' is replaced with
+				// just '<br>' element which breaks accent composition in an empty paragraph. It also throws an error while
+				// refreshing mappings in a renderer. Simulate such behaviour (#1354).
+				domRoot.childNodes[ 1 ].innerHTML = '<br>';
+
+				viewRoot._removeChildren( 1 );
+				viewRoot._insertChild( 1, parse( '<container:p></container:p>' ) );
+
+				renderer.markToSync( 'children', viewRoot );
+				renderer.render();
+
+				expect( domRoot.innerHTML ).to.equal( expected );
+			} );
 		} );
 	} );