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

Remove also unnamed spans to avoid polluting the content with   on Chrome (see https://github.com/ckeditor/ckeditor5-clipboard/issues/2#issuecomment-312635209).

Piotrek Koszuliński 8 лет назад
Родитель
Сommit
51b8ef4971

+ 1 - 1
packages/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js

@@ -15,7 +15,7 @@
  */
 export default function normalizeClipboardData( data ) {
 	return data
-		.replace( /<span class="Apple-converted-space">(\s+)<\/span>/g, ( fullMatch, spaces ) => {
+		.replace( /<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, ( fullMatch, spaces ) => {
 			// Handle the most popular and problematic case when even a single space becomes an nbsp;.
 			// Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.
 			if ( spaces.length == 1 ) {

+ 20 - 0
packages/ckeditor5-clipboard/tests/manual/pasting.html

@@ -17,3 +17,23 @@
 
 	<p>It has <em>bugs</em> that we are aware of – and that we will be working on in the next few iterations of the project. Stay tuned for some updates soon!</p>
 </div>
+
+<h2 style="margin-top: 100px">Some rich content to copy</h2>
+
+<p>Copy also this content to check how pasting from outside of the editor works. Feel free to also use content from other websites.</p>
+
+<p>This is the <a href="http://ckeditor.com/blog/Third-Developer-Preview-of-CKEditor-5-Available">third developer preview</a> of <strong>CKEditor&nbsp;5</strong>.</p>
+
+<p>After 2 years of work, building the next generation editor from scratch and closing over 670 tickets, we created a highly <strong>extensible and flexible architecture</strong> which consists of an <strong>amazing editing framework</strong> and <strong>editing solutions</strong> that will be built on top of it.</p>
+
+<h3>Notes</h3>
+
+<p><a href="https://ckeditor5.github.io">CKEditor&nbsp;5</a> is <i>under heavy development</i> and this demo is not production-ready software. For example:</p>
+
+<ul>
+	<li><strong>only Chrome, Opera and Safari are supported</strong>,</li>
+	<li>Firefox requires enabling the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/onselectionchange">&ldquo;dom.select_events.enabled&rdquo;</a> option,</li>
+	<li><a href="https://github.com/ckeditor/ckeditor5/issues/342">support for pasting</a> is under development.</li>
+</ul>
+
+<p>It has <em>bugs</em> that we are aware of – and that we will be working on in the next few iterations of the project. Stay tuned for some updates soon!</p>

+ 83 - 0
packages/ckeditor5-clipboard/tests/pasting-integration.js

@@ -115,6 +115,89 @@ describe( 'Pasting – integration', () => {
 				} );
 		} );
 	} );
+
+	describe( 'white spaces', () => {
+		// See https://github.com/ckeditor/ckeditor5-clipboard/issues/2#issuecomment-310417731.
+		it( 'keeps spaces around inline styles (Chrome)', () => {
+			return ClassicTestEditor
+				.create( element, { plugins: [ Clipboard, Paragraph, Bold, Italic, Link ] } )
+				.then( editor => {
+					setData( editor.document, '<paragraph>x[]y</paragraph>' );
+
+					pasteHtml( editor,
+						'<meta charset=\'utf-8\'>' +
+						'<span style="color: rgb(0, 0, 0); font-family: Times;">This is the<span>\u00a0</span></span>' +
+						'<a href="url" style="font-family: Times; font-size: medium;">third developer preview</a>' +
+						'<span style="color: rgb(0, 0, 0); font-family: Times;"><span>\u00a0</span>of<span>\u00a0</span></span>' +
+						'<strong style="color: rgb(0, 0, 0); font-family: Times;">CKEditor\u00a05</strong>' +
+						'<span style="color: rgb(0, 0, 0); font-family: Times;">.</span>'
+					);
+
+					expect( getData( editor.document ) ).to.equal(
+						'<paragraph>' +
+							'xThis is the ' +
+							'<$text linkHref="url">third developer preview</$text> of <$text bold="true">CKEditor\u00a05</$text>' +
+							'.[]y' +
+						'</paragraph>'
+					);
+
+					return editor.destroy();
+				} );
+		} );
+
+		// See https://github.com/ckeditor/ckeditor5-clipboard/issues/2#issuecomment-310417731.
+		it( 'keeps spaces around inline styles (Safari)', () => {
+			return ClassicTestEditor
+				.create( element, { plugins: [ Clipboard, Paragraph, Bold, Italic, Link ] } )
+				.then( editor => {
+					setData( editor.document, '<paragraph>x[]y</paragraph>' );
+
+					/* eslint-disable max-len */
+					pasteHtml( editor,
+						'<span style="color: rgb(0, 0, 0); font-family: -webkit-standard;">This is the<span class="Apple-converted-space">\u00a0</span></span>' +
+						'<a href="url" style="font-family: -webkit-standard; font-style: normal;">third developer preview</a>' +
+						'<span style="color: rgb(0, 0, 0); font-family: -webkit-standard;"><span class="Apple-converted-space">\u00a0</span>of<span class="Apple-converted-space">\u00a0</span></span>' +
+						'<strong style="color: rgb(0, 0, 0); font-family: -webkit-standard;">CKEditor\u00a05</strong>' +
+						'<span style="color: rgb(0, 0, 0); font-family: -webkit-standard;">.</span>'
+					);
+					/* eslint-enable max-len */
+
+					expect( getData( editor.document ) ).to.equal(
+						'<paragraph>' +
+							'xThis is the ' +
+							'<$text linkHref="url">third developer preview</$text> of <$text bold="true">CKEditor\u00a05</$text>' +
+							'.[]y' +
+						'</paragraph>'
+					);
+
+					return editor.destroy();
+				} );
+		} );
+
+		it( 'keeps spaces around inline styles (Firefox)', () => {
+			return ClassicTestEditor
+				.create( element, { plugins: [ Clipboard, Paragraph, Bold, Italic, Link ] } )
+				.then( editor => {
+					setData( editor.document, '<paragraph>x[]y</paragraph>' );
+
+					// Note, when copying the HTML from Firefox's console you'll see only normal spaces,
+					// but when you check it later in the model it's still an nbsp.
+					pasteHtml( editor,
+						'This is the <a href="url">third developer preview</a> of <strong>CKEditor\u00a05</strong>.'
+					);
+
+					expect( getData( editor.document ) ).to.equal(
+						'<paragraph>' +
+							'xThis is the ' +
+							'<$text linkHref="url">third developer preview</$text> of <$text bold="true">CKEditor\u00a05</$text>' +
+							'.[]y' +
+						'</paragraph>'
+					);
+
+					return editor.destroy();
+				} );
+		} );
+	} );
 } );
 
 function pasteHtml( editor, html ) {

+ 41 - 1
packages/ckeditor5-clipboard/tests/utils/normalizeclipboarddata.js

@@ -5,7 +5,7 @@
 
 import normalizeClipboardData from '../../src/utils/normalizeclipboarddata';
 
-describe( 'normalizeClipboardData', () => {
+describe( 'normalizeClipboardData()', () => {
 	it( 'should strip all span.Apple-converted-space', () => {
 		expect( normalizeClipboardData(
 			'<span class="Apple-converted-space"> \t\n</span>x<span class="Apple-converted-space">\u00a0\u00a0</span>'
@@ -17,4 +17,44 @@ describe( 'normalizeClipboardData', () => {
 			normalizeClipboardData( '<span class="Apple-converted-space"> </span>x<span class="Apple-converted-space">\u00a0</span>' )
 		).to.equal( ' x ' );
 	} );
+
+	it( 'should strip all spans with no attributes', () => {
+		expect( normalizeClipboardData(
+			'<span> \t\n</span>x<span>\u00a0\u00a0</span>'
+		) ).to.equal( ' \t\nx\u00a0\u00a0' );
+	} );
+
+	it( 'should replace spans with no attributes with a normal space', () => {
+		expect(
+			normalizeClipboardData( '<span> </span>x<span>\u00a0</span>' )
+		).to.equal( ' x ' );
+	} );
+
+	it( 'should not strip spans with no attributes if they contain anything but spaces', () => {
+		expect(
+			normalizeClipboardData( '<span> a</span>x<span>b\u00a0</span>x<span>c</span>' )
+		).to.equal( '<span> a</span>x<span>b\u00a0</span>x<span>c</span>' );
+	} );
+
+	it( 'should not replace spans of length 1+ with normal space', () => {
+		expect(
+			normalizeClipboardData( '<span>  </span>x<span>\u00a0 </span>x<span>\u00a0\u00a0</span>x<span> \u00a0</span>' )
+		).to.equal( '  x\u00a0 x\u00a0\u00a0x \u00a0' );
+	} );
+
+	it( 'should not strip spans with any attribute (except span.Apple-converted-space)', () => {
+		const input =
+			'<span style="color: red"> </span>x' +
+			'<span foo="1">\u00a0</span>x' +
+			'<span foo> </span>x' +
+			'<span class="bar">\u00a0</span>';
+
+		expect( normalizeClipboardData( input ) ).to.equal( input );
+	} );
+
+	it( 'should not be greedy', () => {
+		expect(
+			normalizeClipboardData( '<span class="Apple-converted-space"> </span><span foo>  </span><span>a</span>' )
+		).to.equal( ' <span foo>  </span><span>a</span>' );
+	} );
 } );

+ 1 - 1
packages/ckeditor5-clipboard/tests/utils/plaintexttohtml.js

@@ -5,7 +5,7 @@
 
 import plainTextToHtml from '../../src/utils/plaintexttohtml';
 
-describe( 'plainTextToHtml', () => {
+describe( 'plainTextToHtml()', () => {
 	it( 'encodes < and >', () => {
 		expect( plainTextToHtml( 'x y <z>' ) ).to.equal( 'x y &lt;z&gt;' );
 	} );

+ 1 - 1
packages/ckeditor5-clipboard/tests/utils/viewtoplaintext.js

@@ -7,7 +7,7 @@ import viewToPlainText from '../../src/utils/viewtoplaintext';
 
 import { parse as parseView } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 
-describe( 'viewToPlainText', () => {
+describe( 'viewToPlainText()', () => {
 	function test( viewString, expectedText ) {
 		const view = parseView( viewString );
 		const text = viewToPlainText( view );