8
0
Просмотр исходного кода

Merge pull request #50 from ckeditor/t/49

Changed: clean   inserted by browser.
Piotrek Koszuliński 9 лет назад
Родитель
Сommit
74d2822952

+ 23 - 4
packages/ckeditor5-typing/src/input.js

@@ -168,8 +168,21 @@ class MutationHandler {
 			return;
 		}
 
-		const diffResult = diff( mutation.oldText, mutation.newText );
-		const changes = diffToChanges( diffResult, mutation.newText );
+		// Replace   inserted by the browser with normal space.
+		// We want only normal spaces in the model and in the view. Renderer and DOM Converter will be then responsible
+		// for rendering consecutive spaces using  , but the model and the view has to be clear.
+		// Other feature may introduce inserting non-breakable space on specific key stroke (for example shift + space).
+		// However then it will be handled outside of mutations, like enter key is.
+		// The replacing is here because it has to be done before `diff` and `diffToChanges` functions, as they
+		// take `newText` and compare it to (cleaned up) view.
+		// It could also be done in mutation observer too, however if any outside plugin would like to
+		// introduce additional events for mutations, they would get already cleaned up version (this may be good or not).
+		const newText = mutation.newText.replace( /\u00A0/g, ' ' );
+		// To have correct `diffResult`, we also compare view node text data with   replaced by space.
+		const oldText = mutation.oldText.replace( /\u00A0/g, ' ' );
+
+		const diffResult = diff( oldText, newText );
+		const changes = diffToChanges( diffResult, newText );
 
 		for ( let change of changes ) {
 			const viewPos = new ViewPosition( mutation.node, change.index );
@@ -199,7 +212,6 @@ class MutationHandler {
 			return;
 		}
 
-		// Which is text.
 		const diffResult = diff( mutation.oldChildren, mutation.newChildren, compare );
 		const changes = diffToChanges( diffResult, mutation.newChildren );
 
@@ -210,13 +222,20 @@ class MutationHandler {
 
 		const change = changes[ 0 ];
 
+		// Which is text.
 		if ( !( change.values[ 0 ] instanceof ViewText ) ) {
 			return;
 		}
 
 		const viewPos = new ViewPosition( mutation.node, change.index );
 		const modelPos = this.editing.mapper.toModelPosition( viewPos );
-		const insertedText = change.values[ 0 ].data;
+		let insertedText = change.values[ 0 ].data;
+
+		// Replace   inserted by the browser with normal space.
+		// See comment in `_handleTextMutation`.
+		// In this case we don't need to do this before `diff` because we diff whole nodes.
+		// Just change   in case there are some.
+		insertedText = insertedText.replace( /\u00A0/g, ' ' );
 
 		this._insert( modelPos, insertedText );
 

+ 1 - 1
packages/ckeditor5-typing/tests/tickets/40/1.md

@@ -1,5 +1,5 @@
 @bender-ui: collapsed
-@bender-tags: ticket, 40, 0.3.0, iteration3
+@bender-tags: ticket, 40, iteration3
 
 ### Issue [#40](https://github.com/ckeditor/ckeditor5-typing/issues/40) manual test
 

+ 9 - 0
packages/ckeditor5-typing/tests/tickets/49/1.html

@@ -0,0 +1,9 @@
+<head>
+	<link rel="stylesheet" href="%APPS_DIR%ckeditor/build/modules/amd/theme/ckeditor.css">
+</head>
+
+<div id="editor">
+	<p>This is an editor instance.</p>
+</div>
+<br /><br />
+<button id="nbsp">Insert &amp;nbsp;</button>

+ 45 - 0
packages/ckeditor5-typing/tests/tickets/49/1.js

@@ -0,0 +1,45 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals console:false, document, window */
+
+import ClassicEditor from '/ckeditor5/editor-classic/classic.js';
+import { getData as getModelData } from '/ckeditor5/engine/dev-utils/model.js';
+import { getData as getViewData } from '/ckeditor5/engine/dev-utils/view.js';
+
+ClassicEditor.create( document.querySelector( '#editor' ), {
+	features: [ 'enter', 'typing', 'paragraph' ],
+	toolbar: []
+} )
+.then( editor => {
+	window.editor = editor;
+
+	editor.document.schema.allow( { name: '$text', inside: '$root' } );
+
+	const editable = editor.ui.editableElement;
+
+	document.querySelector( '#nbsp' ).addEventListener( 'click', () => {
+		editor.document.enqueueChanges( () => {
+			editor.document.selection.collapseToStart();
+			editor.document.batch().weakInsert( editor.document.selection.getFirstPosition(), '\u00A0' );
+		} );
+	} );
+
+	editor.document.on( 'changesDone', () => {
+		console.clear();
+
+		const modelData = getModelData( editor.document, { withoutSelection: true } );
+		console.log( 'model:', modelData.replace( /\u00A0/g, '&nbsp;' ) );
+
+		const viewData = getViewData( editor.editing.view, { withoutSelection: true } );
+		console.log( 'view:', viewData.replace( /\u00A0/g, '&nbsp;' ) );
+
+		console.log( 'dom:', editable.innerHTML );
+		console.log( 'editor.getData', editor.getData() );
+	}, { priority: 'lowest' } );
+} )
+.catch( err => {
+	console.error( err.stack );
+} );

+ 18 - 0
packages/ckeditor5-typing/tests/tickets/49/1.md

@@ -0,0 +1,18 @@
+@bender-ui: collapsed
+@bender-tags: ticket, 49, iteration4
+
+### Issue [#49](https://github.com/ckeditor/ckeditor5-typing/issues/49) manual test
+
+Non-breakable spaces created by browser after using <kbd>space</kbd> should be changed to normal space characters when
+inserted to model and view. Still, `&nbsp;` have to be correctly rendered in DOM.
+
+Multiple consecutive spaces should be allowed, as well as spaces at the beginning or end of element.
+
+Open console and start using <kbd>space</kbd>. After each change, console is refreshed with output:
+* There should be no `&nbsp;` inserted in view and model after using <kbd>space</kbd>.
+* There should be `&nbsp;` in DOM and `getData` output, where needed.
+
+Use `editor.setData()` to test whether whitespaces in input HTML are correctly removed and `&nbsp;` are correctly
+saved in model and view. `&nbsp;` inserted through `editor.setData()` should be kept, not changed to normal spaces.
+
+Use the button to test whether `&nbsp;`s are correctly preserved in model, view and DOM.