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

Merge branch 'master' into t/71

Szymon Kupś 8 лет назад
Родитель
Сommit
d1c0862cba

+ 50 - 3
packages/ckeditor5-image/src/imagecaption/imagecaptionengine.js

@@ -81,6 +81,12 @@ export default class ImageCaptionEngine extends Plugin {
 		// Model to view converter for the editing pipeline.
 		editing.modelToView.on( 'insert:caption', captionModelToView( this._createCaption ) );
 
+		// Always show caption in view when something is inserted in model.
+		editing.modelToView.on( 'insert', ( evt, data ) => this._fixCaptionVisibility( data.item ), { priority: 'high' } );
+
+		// Hide caption when everything is removed from it.
+		editing.modelToView.on( 'remove', ( evt, data ) => this._fixCaptionVisibility( data.sourcePosition.parent ), { priority: 'high' } );
+
 		// Update view before each rendering.
 		this.listenTo( viewDocument, 'render', () => this._updateCaptionVisibility(), { priority: 'high' } );
 	}
@@ -99,7 +105,7 @@ export default class ImageCaptionEngine extends Plugin {
 
 		// Hide last selected caption if have no child elements.
 		if ( this._lastSelectedCaption && !this._lastSelectedCaption.childCount ) {
-			this._lastSelectedCaption.addClass( 'ck-editable_hidden' );
+			this._lastSelectedCaption.addClass( 'ck-hidden' );
 		}
 
 		// If whole image widget is selected.
@@ -115,10 +121,34 @@ export default class ImageCaptionEngine extends Plugin {
 		}
 
 		if ( viewCaption ) {
-			viewCaption.removeClass( 'ck-editable_hidden' );
+			viewCaption.removeClass( 'ck-hidden' );
 			this._lastSelectedCaption = viewCaption;
 		}
 	}
+
+	/**
+	 * Fixes caption visibility during model to view conversion.
+	 * Checks if changed node is placed inside caption element and fixes it's visibility in the view.
+	 *
+	 * @private
+	 * @param {module:engine/model/node~Node} node
+	 */
+	_fixCaptionVisibility( node ) {
+		const modelCaption = getParentCaption( node );
+		const mapper = this.editor.editing.mapper;
+
+		if ( modelCaption ) {
+			const viewCaption = mapper.toViewElement( modelCaption );
+
+			if ( viewCaption ) {
+				if ( modelCaption.childCount ) {
+					viewCaption.removeClass( 'ck-hidden' );
+				} else {
+					viewCaption.addClass( 'ck-hidden' );
+				}
+			}
+		}
+	}
 }
 
 // Checks whether data inserted to the model document have image element that has no caption element inside it.
@@ -172,7 +202,7 @@ function captionModelToView( elementCreator, hide = true ) {
 
 			// Hide if empty.
 			if ( !captionElement.childCount ) {
-				viewCaption.addClass( 'ck-editable_hidden' );
+				viewCaption.addClass( 'ck-hidden' );
 			}
 
 			insertViewCaptionAndBind( viewCaption, data.item, viewImage, conversionApi.mapper );
@@ -193,3 +223,20 @@ function insertViewCaptionAndBind( viewCaption, modelCaption, viewImage, mapper
 	viewWriter.insert( viewPosition, viewCaption );
 	mapper.bindElements( modelCaption, viewCaption );
 }
+
+/**
+ * Checks if provided node or one of its ancestors is caption element and returns it.
+ *
+ * @param {module:engine/model/node~Node} node
+ * @returns {module:engine/model/element~Element|null}
+ */
+function getParentCaption( node ) {
+	const ancestors = node.getAncestors( { includeNode: true } );
+	const caption = ancestors.find( ancestor => ancestor.name == 'caption' );
+
+	if ( caption && caption.parent && caption.parent.name == 'image' ) {
+		return caption;
+	}
+
+	return null;
+}

+ 63 - 6
packages/ckeditor5-image/tests/imagecaption/imagecaptionengine.js

@@ -80,7 +80,7 @@ describe( 'ImageCaptionEngine', () => {
 				expect( editor.getData() ).to.equal( '<figure class="image"><img src="img.png"><figcaption>Foo bar baz.</figcaption></figure>' );
 			} );
 
-			it( 'should convert caption to figcaption with hidden class if it\'s empty', () => {
+			it( 'should not convert caption to figcaption if it\'s empty', () => {
 				setModelData( document, '<image src="img.png"><caption></caption></image>' );
 
 				expect( editor.getData() ).to.equal( '<figure class="image"><img src="img.png"></figure>' );
@@ -114,7 +114,7 @@ describe( 'ImageCaptionEngine', () => {
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 					'<figure class="image ck-widget" contenteditable="false">' +
 						'<img src="img.png"></img>' +
-						'<figcaption class="ck-placeholder ck-editable ck-editable_hidden" contenteditable="true" data-placeholder="Enter image caption">' +
+						'<figcaption class="ck-placeholder ck-editable ck-hidden" contenteditable="true" data-placeholder="Enter image caption">' +
 						'</figcaption>' +
 					'</figure>'
 				);
@@ -147,6 +147,63 @@ describe( 'ImageCaptionEngine', () => {
 					'<figure class="image ck-widget" contenteditable="false"><img src="img.png"></img><span></span>Foo bar baz.</figure>'
 				);
 			} );
+
+			it( 'should show caption when something is inserted inside', () => {
+				setModelData( document, '<image src="img.png"><caption></caption></image>' );
+				const image = document.getRoot().getChild( 0 );
+				const caption = image.getChild( 0 );
+
+				document.enqueueChanges( () => {
+					const batch = document.batch();
+					batch.insert( ModelPosition.createAt( caption ), 'foo bar' );
+				} );
+
+				expect( getViewData( viewDocument ) ).to.equal(
+					'[]<figure class="image ck-widget" contenteditable="false">' +
+						'<img src="img.png"></img>' +
+						'<figcaption class="ck-editable" contenteditable="true" data-placeholder="Enter image caption">' +
+							'foo bar' +
+						'</figcaption>' +
+					'</figure>'
+				);
+			} );
+
+			it( 'should hide when everything is removed from caption', () => {
+				setModelData( document, '<image src="img.png"><caption>foo bar baz</caption></image>' );
+				const image = document.getRoot().getChild( 0 );
+				const caption = image.getChild( 0 );
+
+				document.enqueueChanges( () => {
+					const batch = document.batch();
+					batch.remove( ModelRange.createIn( caption ) );
+				} );
+
+				expect( getViewData( viewDocument ) ).to.equal(
+					'[]<figure class="image ck-widget" contenteditable="false">' +
+						'<img src="img.png"></img>' +
+						'<figcaption class="ck-editable ck-hidden ck-placeholder" contenteditable="true" data-placeholder="Enter image caption">' +
+						'</figcaption>' +
+					'</figure>'
+				);
+			} );
+
+			it( 'should show when not everything is removed from caption', () => {
+				setModelData( document, '<image src="img.png"><caption>foo bar baz</caption></image>' );
+				const image = document.getRoot().getChild( 0 );
+				const caption = image.getChild( 0 );
+
+				document.enqueueChanges( () => {
+					const batch = document.batch();
+					batch.remove( ModelRange.createFromParentsAndOffsets( caption, 0, caption, 8 ) );
+				} );
+
+				expect( getViewData( viewDocument ) ).to.equal(
+					'[]<figure class="image ck-widget" contenteditable="false">' +
+					'<img src="img.png"></img>' +
+						'<figcaption class="ck-editable" contenteditable="true" data-placeholder="Enter image caption">baz</figcaption>' +
+					'</figure>'
+				);
+			} );
 		} );
 	} );
 
@@ -166,7 +223,7 @@ describe( 'ImageCaptionEngine', () => {
 			expect( getViewData( viewDocument ) ).to.equal(
 				'[]<figure class="image ck-widget" contenteditable="false">' +
 					'<img alt="" src=""></img>' +
-					'<figcaption class="ck-placeholder ck-editable ck-editable_hidden" contenteditable="true" data-placeholder="Enter image caption">' +
+					'<figcaption class="ck-placeholder ck-editable ck-hidden" contenteditable="true" data-placeholder="Enter image caption">' +
 					'</figcaption>' +
 				'</figure>'
 			);
@@ -229,7 +286,7 @@ describe( 'ImageCaptionEngine', () => {
 			expect( getViewData( viewDocument ) ).to.equal(
 				'[]<figure class="image ck-widget" contenteditable="false">' +
 					'<img src=""></img>' +
-					'<figcaption class="ck-placeholder ck-editable ck-editable_hidden" contenteditable="true" data-placeholder="Enter image caption">' +
+					'<figcaption class="ck-placeholder ck-editable ck-hidden" contenteditable="true" data-placeholder="Enter image caption">' +
 					'</figcaption>' +
 				'</figure>'
 			);
@@ -256,7 +313,7 @@ describe( 'ImageCaptionEngine', () => {
 			expect( getViewData( viewDocument ) ).to.equal(
 				'[]<figure class="image ck-widget" contenteditable="false">' +
 					'<img src=""></img>' +
-					'<figcaption class="ck-placeholder ck-editable ck-editable_hidden" contenteditable="true" data-placeholder="Enter image caption">' +
+					'<figcaption class="ck-placeholder ck-editable ck-hidden" contenteditable="true" data-placeholder="Enter image caption">' +
 					'</figcaption>' +
 				'</figure>'
 			);
@@ -336,7 +393,7 @@ describe( 'ImageCaptionEngine', () => {
 				expect( getViewData( viewDocument ) ).to.equal(
 					'[]<figure class="image ck-widget" contenteditable="false">' +
 						'<img src=""></img>' +
-						'<figcaption class="ck-editable ck-editable_hidden ck-placeholder" contenteditable="true" data-placeholder="Enter image caption">' +
+						'<figcaption class="ck-editable ck-hidden ck-placeholder" contenteditable="true" data-placeholder="Enter image caption">' +
 						'</figcaption>' +
 					'</figure>'
 				);

+ 6 - 8
packages/ckeditor5-image/theme/imagecaption/theme.scss

@@ -2,16 +2,14 @@
 // For licensing, see LICENSE.md or http://ckeditor.com/license
 
 @import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_colors.scss';
+@import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_spacing.scss';
+@import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_fonts.scss';
 
-.ck-widget.image {
-	figcaption.ck-editable {
+.ck-editor__editable {
+	.image > figcaption {
 		background-color: ck-color( 'foreground' );
-		padding: 10px;
-		font-size: .8em;
+		padding: ck-spacing();
+		font-size: ck-font-size( -1 );
 		color: ck-color( 'text', 40 );
-
-		&_hidden {
-			display: none;
-		}
 	}
 }

+ 17 - 16
packages/ckeditor5-image/theme/theme.scss

@@ -1,25 +1,26 @@
 // Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
 // For licensing, see LICENSE.md or http://ckeditor.com/license
 
-// Image widget's styles.
-.image {
-	text-align: center;
-	clear: both;
+.ck-editor__editable {
+	.image {
+		text-align: center;
+		clear: both;
 
-	&.image-style-side {
-		float: right;
-		margin-left: 0.8em;
-		max-width: 50%;
+		&.image-style-side {
+			float: right;
+			margin-left: 0.8em;
+			max-width: 50%;
+		}
 	}
-}
 
-.image > img {
-	// Prevent unnecessary margins caused by line-height (see #44).
-	display: block;
+	.image > img {
+		// Prevent unnecessary margins caused by line-height (see #44).
+		display: block;
 
-	// Center the image if its width is smaller than content's width.
-	margin: 0 auto;
+		// Center the image if its width is smaller than content's width.
+		margin: 0 auto;
 
-	// Make sure the image never exceeds the size of the parent container (#67).
-	max-width: 100%;
+		// Make sure the image never exceeds the size of the parent container (#67).
+		max-width: 100%;
+	}
 }

+ 18 - 14
packages/ckeditor5-image/theme/widget/theme.scss

@@ -4,34 +4,38 @@
 @import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_colors.scss';
 @import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_shadow.scss';
 @import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_states.scss';
+@import '~@ckeditor/ckeditor5-theme-lark/theme/helpers/_spacing.scss';
+
+@include ck-color-add( (
+	'widget-blurred': #ddd,
+	'widget-hover': yellow
+) );
+
+$widget-outline-thickness: 2px;
 
 .ck-widget {
-	margin: 10px 0;
+	margin: ck-spacing() 0;
 	padding: 0;
 
 	&.ck-widget_selected, &.ck-widget_selected:hover {
-		outline: 2px solid #ace;
+		outline: $widget-outline-thickness solid ck-color( 'focus' );
 	}
 
 	.ck-editor__editable.ck-blurred &.ck-widget_selected {
-		outline: 2px solid #ddd;
+		outline: $widget-outline-thickness solid ck-color( 'widget-blurred' );
 	}
 
 	&:hover {
-		outline: 2px solid yellow;
+		outline: $widget-outline-thickness solid ck-color( 'widget-hover' );
 	}
 
 	.ck-editable {
-		// The `:focus` styles is applied before `.focused` class inside editables.
-		// These styles show different border for a blink of an eye.
-		&:focus {
-			&.ck-editable_focused {
-				@include ck-focus-ring( 'outline' );
-				@include ck-box-shadow( $ck-inner-shadow );
-				background-color: ck-color( 'background' );;
-			}
-			outline: none;
-			box-shadow: none;
+		// The `:focus` style is applied before `.ck-editable_focused` class is rendered in the view.
+		// These styles show a different border for a blink of an eye, so `:focus` need to have same styles applied.
+		&.ck-editable_focused, &:focus {
+			@include ck-focus-ring( 'outline' );
+			@include ck-box-shadow( $ck-inner-shadow );
+			background-color: ck-color( 'background' );
 		}
 	}
 }