Przeglądaj źródła

Merge branch 'master' into t/229

Piotrek Koszuliński 6 lat temu
rodzic
commit
848f106740

+ 13 - 7
packages/ckeditor5-link/src/linkediting.js

@@ -156,17 +156,23 @@ export default class LinkEditing extends Plugin {
 				model: decorator.id,
 				view: ( manualDecoratorName, writer ) => {
 					if ( manualDecoratorName ) {
-						const element = writer.createAttributeElement(
-							'a',
-							manualDecorators.get( decorator.id ).attributes,
-							{
-								priority: 5
-							}
-						);
+						const attributes = manualDecorators.get( decorator.id ).attributes;
+						const element = writer.createAttributeElement( 'a', attributes, { priority: 5 } );
 						writer.setCustomProperty( 'link', true, element );
+
 						return element;
 					}
 				} } );
+
+			editor.conversion.for( 'upcast' ).elementToAttribute( {
+				view: {
+					name: 'a',
+					attributes: manualDecorators.get( decorator.id ).attributes
+				},
+				model: {
+					key: decorator.id
+				}
+			} );
 		} );
 	}
 

+ 84 - 0
packages/ckeditor5-link/tests/linkediting.js

@@ -587,5 +587,89 @@ describe( 'LinkEditing', () => {
 				expect( editor.getData() ).to.equal( '<p><a href="http://example.com">foo</a>bar</p>' );
 			} );
 		} );
+
+		describe( 'upcast converter', () => {
+			it( 'should upcast attributes from initial data', done => {
+				VirtualTestEditor
+					.create( {
+						initialData: '<p><a href="url" target="_blank" rel="noopener noreferrer" download="file">Foo</a>' +
+							'<a href="example.com" download="file">Bar</a></p>',
+						plugins: [ Paragraph, LinkEditing, Enter ],
+						link: {
+							decorators: {
+								isExternal: {
+									mode: 'manual',
+									label: 'Open in a new window',
+									attributes: {
+										target: '_blank',
+										rel: 'noopener noreferrer'
+									}
+								},
+								isDownloadable: {
+									mode: 'manual',
+									label: 'Downloadable',
+									attributes: {
+										download: 'file'
+									}
+								}
+							}
+						}
+					} )
+					.then( newEditor => {
+						editor = newEditor;
+						model = editor.model;
+
+						expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
+							'<paragraph>' +
+								'<$text linkHref="url" linkIsDownloadable="true" linkIsExternal="true">Foo</$text>' +
+								'<$text linkHref="example.com" linkIsDownloadable="true">Bar</$text>' +
+							'</paragraph>'
+						);
+					} )
+					.then( done )
+					.catch( done );
+			} );
+
+			it( 'should not upcast partial and incorrect attributes', done => {
+				VirtualTestEditor
+					.create( {
+						initialData: '<p><a href="url" target="_blank" download="something">Foo</a>' +
+							'<a href="example.com" download="test">Bar</a></p>',
+						plugins: [ Paragraph, LinkEditing, Enter ],
+						link: {
+							decorators: {
+								isExternal: {
+									mode: 'manual',
+									label: 'Open in a new window',
+									attributes: {
+										target: '_blank',
+										rel: 'noopener noreferrer'
+									}
+								},
+								isDownloadable: {
+									mode: 'manual',
+									label: 'Downloadable',
+									attributes: {
+										download: 'file'
+									}
+								}
+							}
+						}
+					} )
+					.then( newEditor => {
+						editor = newEditor;
+						model = editor.model;
+
+						expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
+							'<paragraph>' +
+								'<$text linkHref="url">Foo</$text>' +
+								'<$text linkHref="example.com">Bar</$text>' +
+							'</paragraph>'
+						);
+					} )
+					.then( done )
+					.catch( done );
+			} );
+		} );
 	} );
 } );

+ 5 - 5
packages/ckeditor5-link/tests/manual/linkdecorator.html

@@ -1,16 +1,16 @@
 <h2>Manual decorators</h2>
 <div id="editor">
-	<p>This is <a href="http://ckeditor.com">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
-	<p>This is <a href="//ckeditor.com">CKEditor5</a> as schemaless url.</p>
+	<p>This is <a href="http://ckeditor.com" target="_blank" rel="noopener noreferrer">CKEditor5</a> from <a href="http://cksource.com" download="download" target="_blank" rel="noopener noreferrer" >CKSource</a>.</p>
+	<p>This is <a href="//ckeditor.com" class="gallery">CKEditor5</a> as schemaless url.</p>
 	<p>This is <a href="#anchor">anchor</a> on this page.</p>
-	<p>This is some random <a href="ftp://127.0.0.1">ftp address</a>.</p>
+	<p>This is some random <a href="ftp://127.0.0.1" download="download">ftp address</a>.</p>
 	<p>This is some <a href="mailto:random@user.org">mail</a>.</p>
-	<p>This is some <a href="tel:123456789">phone number</a>.</p>
+	<p>This is some <a href="tel:123456789">phone number</a> with gallery decorator</p>
 </div>
 
 <h2>Automatic decorators</h2>
 <div id="editor2">
-	<p>This is <a href="http://ckeditor.com">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
+	<p>This is <a href="http://ckeditor.com" target="_blank" rel="noopener noreferrer" download="download">CKEditor5</a> from <a href="http://cksource.com">CKSource</a>.</p>
 	<p>This is <a href="//ckeditor.com">CKEditor5</a> as schemaless url.</p>
 	<p>This is <a href="#anchor">anchor</a> on this page.</p>
 	<p>This is some random <a href="ftp://127.0.0.1">ftp address</a>.</p>

+ 5 - 8
packages/ckeditor5-link/tests/manual/linkdecorator.js

@@ -3,7 +3,7 @@
  * For licensing, see LICENSE.md.
  */
 
-/* globals console:false, window, document */
+/* globals console:false, window, document, CKEditorInspector */
 
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import Enter from '@ckeditor/ckeditor5-enter/src/enter';
@@ -16,6 +16,8 @@ import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
 // Just to have nicely styles switchbutton;
 import '@ckeditor/ckeditor5-theme-lark/theme/ckeditor5-ui/components/list/list.css';
 
+window.editors = {};
+
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
 		plugins: [ Link, Typing, Paragraph, Clipboard, Undo, Enter ],
@@ -48,10 +50,7 @@ ClassicEditor
 		}
 	} )
 	.then( editor => {
-		if ( !window.editors ) {
-			window.editors = {};
-		}
-		window.editor = editor;
+		CKEditorInspector.attach( 'manual', editor );
 		window.editors.manualDecorators = editor;
 	} )
 	.catch( err => {
@@ -83,9 +82,7 @@ ClassicEditor
 		}
 	} )
 	.then( editor => {
-		if ( !window.editors ) {
-			window.editors = {};
-		}
+		CKEditorInspector.attach( 'automatic', editor );
 		window.editors.automaticDecorators = editor;
 	} )
 	.catch( err => {

+ 13 - 8
packages/ckeditor5-link/tests/manual/linkdecorator.md

@@ -4,12 +4,17 @@
 
 1. Should be available for every link.
 2. Should be applied to the content only when "Save" was clicked.
-3. There should be 3 manual decorators available:
-  * Open in new a new tab
-  * Downloadable
-  * Gallery link
-4. State of the decorator switches should reflect the model of the currently selected link.
-5. Switch buttons should be focusable (with the tab key), after the URL input. The "save" and "cancel" buttons should be focused last.
+3. There should be initially set some decorators over specific links based on source data of the editor:
+    * `CKEditor5` has: "Open in a new tab"
+    * `CKSource` has: "Open in a new tab" and "Downloadable"
+    * `CKEditor5` (schemaless) has: "Gallery"
+    * `ftp address` has: "Downloadable"
+4. There should be 3 manual decorators available:
+    * Open in new a new tab
+    * Downloadable
+    * Gallery link
+5. State of the decorator switches should reflect the model of the currently selected link.
+6. Switch buttons should be focusable (with the tab key), after the URL input. The "save" and "cancel" buttons should be focused last.
 
 ### Automatic decorators (window.editors.automaticDecorators).
 
@@ -17,5 +22,5 @@
 2. There should be no changes to the model or the view of the editors.
 3. Decorator data should be added during downcast (run `window.editors.automaticDecorators.getData()` to see how it works).
 4. There are 2 additional decorators in this editor:
-  * phone, which detects all links starting with `tel:` and adds the `phone` CSS class to such link,
-  * internal, which adds the `internal` CSS class to all links starting with `#`.
+    * phone, which detects all links starting with `tel:` and adds the `phone` CSS class to such link,
+    * internal, which adds the `internal` CSS class to all links starting with `#`.