Browse Source

Merge branch 'master' into t/ckeditor5-engine/1556

# Conflicts:
#	tests/image/imageinsertcommand.js
#	tests/image/utils.js
#	tests/imageupload/imageuploadcommand.js
Maciej Gołaszewski 7 years ago
parent
commit
d9267f2e50

+ 1 - 1
packages/ckeditor5-image/package.json

@@ -31,7 +31,7 @@
     "@ckeditor/ckeditor5-typing": "^11.0.2",
     "@ckeditor/ckeditor5-undo": "^10.0.4",
     "eslint": "^5.5.0",
-    "eslint-config-ckeditor5": "^1.0.7",
+    "eslint-config-ckeditor5": "^1.0.9",
     "husky": "^0.14.3",
     "lint-staged": "^7.0.0"
   },

+ 13 - 12
packages/ckeditor5-image/src/image/utils.js

@@ -100,7 +100,9 @@ export function isImageAllowed( model ) {
 	const schema = model.schema;
 	const selection = model.document.selection;
 
-	return isImageAllowedInParent( selection, schema, model ) && checkSelectionWithObject( selection, schema );
+	return isImageAllowedInParent( selection, schema, model ) &&
+		!checkSelectionOnObject( selection, schema ) &&
+		isInOtherImage( selection );
 }
 
 // Checks if image is allowed by schema in optimal insertion parent.
@@ -112,29 +114,28 @@ function isImageAllowedInParent( selection, schema, model ) {
 	return schema.checkChild( parent, 'image' );
 }
 
-// Check used in image commands for additional cases when the command should be disabled:
-//
-// - selection is on object
-// - selection is inside object
+// Check if selection is on object.
 //
 // @returns {Boolean}
-function checkSelectionWithObject( selection, schema ) {
+function checkSelectionOnObject( selection, schema ) {
 	const selectedElement = selection.getSelectedElement();
 
-	const isSelectionOnObject = !!selectedElement && schema.isObject( selectedElement );
-	const isSelectionInObject = !![ ...selection.focus.getAncestors() ].find( ancestor => schema.isObject( ancestor ) );
+	return selectedElement && schema.isObject( selectedElement );
+}
 
-	return !isSelectionOnObject && !isSelectionInObject;
+// Checks if selection is placed in other image (ie. in caption).
+function isInOtherImage( selection ) {
+	return [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'image' ) );
 }
 
 // Returns a node that will be used to insert image with `model.insertContent` to check if image can be placed there.
 function getInsertImageParent( selection, model ) {
 	const insertAt = findOptimalInsertionPosition( selection, model );
 
-	let parent = insertAt.parent;
+	const parent = insertAt.parent;
 
-	if ( !parent.is( '$root' ) ) {
-		parent = parent.parent;
+	if ( parent.isEmpty && !parent.is( '$root' ) ) {
+		return parent.parent;
 	}
 
 	return parent;

+ 1 - 3
packages/ckeditor5-image/src/imagestyle/utils.js

@@ -95,9 +95,7 @@ const defaultIcons = {
  * @returns {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>}
  */
 export function normalizeImageStyles( configuredStyles = [] ) {
-	return configuredStyles
-		.map( _normalizeStyle )
-		.map( style => Object.assign( {}, style ) );
+	return configuredStyles.map( _normalizeStyle );
 }
 
 // Normalizes an image style provided in the {@link module:image/image~ImageConfig#styles}

+ 23 - 6
packages/ckeditor5-image/tests/image/imageinsertcommand.js

@@ -88,13 +88,30 @@ describe( 'ImageInsertCommand', () => {
 			expect( command.isEnabled ).to.be.false;
 		} );
 
-		it( 'should be false when the selection is inside other object', () => {
-			model.schema.register( 'object', { isObject: true, allowIn: '$root' } );
-			model.schema.extend( '$text', { allowIn: 'object' } );
-			editor.conversion.for( 'downcast' ).elementToElement( { model: 'object', view: 'object' } );
-			setModelData( model, '<object>[]</object>' );
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
 
-			expect( command.isEnabled ).to.be.false;
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit>[]</limit></outerObject>' );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
+
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit><paragraph>foo[]</paragraph></limit></outerObject>' );
+
+			expect( command.isEnabled ).to.be.true;
 		} );
 
 		it( 'should be false when schema disallows image', () => {

+ 23 - 6
packages/ckeditor5-image/tests/image/utils.js

@@ -179,13 +179,30 @@ describe( 'image widget utils', () => {
 			expect( isImageAllowed( model ) ).to.be.false;
 		} );
 
-		it( 'should return false when the selection is inside other object', () => {
-			model.schema.register( 'object', { isObject: true, allowIn: '$root' } );
-			model.schema.extend( '$text', { allowIn: 'object' } );
-			editor.conversion.for( 'downcast' ).elementToElement( { model: 'object', view: 'object' } );
-			setModelData( model, '<object>[]</object>' );
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
 
-			expect( isImageAllowed( model ) ).to.be.false;
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit>[]</limit></outerObject>' );
+
+			expect( isImageAllowed( model ) ).to.be.true;
+		} );
+
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
+
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit><paragraph>foo[]</paragraph></limit></outerObject>' );
+
+			expect( isImageAllowed( model ) ).to.be.true;
 		} );
 
 		it( 'should return false when schema disallows image', () => {

+ 23 - 6
packages/ckeditor5-image/tests/imageupload/imageuploadcommand.js

@@ -107,13 +107,30 @@ describe( 'ImageUploadCommand', () => {
 			expect( command.isEnabled ).to.be.false;
 		} );
 
-		it( 'should be false when the selection is inside other object', () => {
-			model.schema.register( 'object', { isObject: true, allowIn: '$root' } );
-			model.schema.extend( '$text', { allowIn: 'object' } );
-			editor.conversion.for( 'downcast' ).elementToElement( { model: 'object', view: 'object' } );
-			setModelData( model, '<object>[]</object>' );
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
 
-			expect( command.isEnabled ).to.be.false;
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit>[]</limit></outerObject>' );
+
+			expect( command.isEnabled ).to.be.true;
+		} );
+
+		it( 'should be true when the selection is inside isLimit element which allows image', () => {
+			model.schema.register( 'outerObject', { isObject: true, isBlock: true, allowIn: '$root' } );
+			model.schema.register( 'limit', { isLimit: true, allowIn: 'outerObject' } );
+			model.schema.extend( '$block', { allowIn: 'limit' } );
+
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'outerObject', view: 'outerObject' } );
+			editor.conversion.for( 'downcast' ).elementToElement( { model: 'limit', view: 'limit' } );
+
+			setModelData( model, '<outerObject><limit><paragraph>foo[]</paragraph></limit></outerObject>' );
+
+			expect( command.isEnabled ).to.be.true;
 		} );
 
 		it( 'should be false when schema disallows image', () => {