Skip to content

Commit

Permalink
Other (image): Encapsulate image replacement into command. Closes #13217
Browse files Browse the repository at this point in the history
 .

Other (image): Added `ReplaceImageSourceCommand` which encapsulates current image URL replacement logic. Closes #13217.
  • Loading branch information
scofalik authored Jan 13, 2023
2 parents e89f021 + 64843fe commit bf96e14
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 7 deletions.
6 changes: 5 additions & 1 deletion packages/ckeditor5-image/src/image/imageediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import { Plugin } from 'ckeditor5/src/core';
import ImageLoadObserver from './imageloadobserver';
import InsertImageCommand from './insertimagecommand';
import ReplaceImageSourceCommand from './replaceimagesourcecommand';
import ImageUtils from '../imageutils';

/**
Expand Down Expand Up @@ -76,9 +77,12 @@ export default class ImageEditing extends Plugin {
} );

const insertImageCommand = new InsertImageCommand( editor );
const replaceImageSourceCommand = new ReplaceImageSourceCommand( editor );

// Register `insertImage` command and add `imageInsert` command as an alias for backward compatibility.
editor.commands.add( 'insertImage', insertImageCommand );
editor.commands.add( 'replaceImageSource', replaceImageSourceCommand );

// `imageInsert` is an alias for backward compatibility.
editor.commands.add( 'imageInsert', insertImageCommand );
}
}
49 changes: 49 additions & 0 deletions packages/ckeditor5-image/src/image/replaceimagesourcecommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

import { Command } from 'ckeditor5/src/core';

/**
* @module image/image/replaceimagesourcecommand
*/

/**
* Replace image source command.
*
* Changes image source to the one provided. Can be executed as follows:
*
* editor.execute( 'replaceImageSource', { source: 'http://url.to.the/image' } );
*
* @extends module:core/command~Command
*/
export default class ReplaceImageSourceCommand extends Command {
/**
* @inheritDoc
*/
refresh() {
const editor = this.editor;
const imageUtils = editor.plugins.get( 'ImageUtils' );
const element = this.editor.model.document.selection.getSelectedElement();

this.isEnabled = imageUtils.isImage( element );
this.value = this.isEnabled ? element.getAttribute( 'src' ) : null;
}

/**
* Executes the command.
*
* @fires execute
* @param {Object} options Options for the executed command.
* @param {String} [options.source] The image source to replace.
*/
execute( options ) {
const image = this.editor.model.document.selection.getSelectedElement();
this.editor.model.change( writer => {
writer.setAttribute( 'src', options.source, image );
writer.removeAttribute( 'srcset', image );
writer.removeAttribute( 'sizes', image );
} );
}
}
9 changes: 3 additions & 6 deletions packages/ckeditor5-image/src/imageinsert/imageinsertui.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default class ImageInsertUI extends Plugin {
const dropdownView = this.dropdownView;
const panelView = dropdownView.panelView;
const imageUtils = this.editor.plugins.get( 'ImageUtils' );
const replaceImageSourceCommand = editor.commands.get( 'replaceImageSource' );

let imageInsertView;

Expand All @@ -133,7 +134,7 @@ export default class ImageInsertUI extends Plugin {

if ( dropdownView.isOpen ) {
if ( imageUtils.isImage( selectedElement ) ) {
imageInsertView.imageURLInputValue = selectedElement.getAttribute( 'src' );
imageInsertView.imageURLInputValue = replaceImageSourceCommand.value;
insertButtonView.label = t( 'Update' );
insertImageViaUrlForm.label = t( 'Update image URL' );
} else {
Expand Down Expand Up @@ -162,11 +163,7 @@ export default class ImageInsertUI extends Plugin {
const selectedElement = editor.model.document.selection.getSelectedElement();

if ( imageUtils.isImage( selectedElement ) ) {
editor.model.change( writer => {
writer.setAttribute( 'src', imageInsertView.imageURLInputValue, selectedElement );
writer.removeAttribute( 'srcset', selectedElement );
writer.removeAttribute( 'sizes', selectedElement );
} );
editor.execute( 'replaceImageSource', { source: imageInsertView.imageURLInputValue } );
} else {
editor.execute( 'insertImage', { source: imageInsertView.imageURLInputValue } );
}
Expand Down
70 changes: 70 additions & 0 deletions packages/ckeditor5-image/tests/image/replaceimagesourcecommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';

import ReplaceImageSourceCommand from '../../src/image/replaceimagesourcecommand';
import ImageBlockEditing from '../../src/image/imageblockediting';
import ImageInlineEditing from '../../src/image/imageinlineediting';

describe( 'ReplaceImageSourceCommand', () => {
let editor, command, model;

beforeEach( () => {
return VirtualTestEditor
.create( {
plugins: [ ImageBlockEditing, ImageInlineEditing, Paragraph ]
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;

command = new ReplaceImageSourceCommand( editor );

const schema = model.schema;
schema.extend( 'imageBlock', { allowAttributes: 'uploadId' } );
} );
} );

afterEach( () => {
return editor.destroy();
} );

describe( 'execute()', () => {
it( 'should change image source', () => {
setModelData( model, '[<imageBlock src="foo/bar.jpg"></imageBlock>]' );

const element = model.document.selection.getSelectedElement();

command.execute( { source: 'bar/foo.jpg' } );

expect( element.getAttribute( 'src' ) ).to.equal( 'bar/foo.jpg' );
} );
} );

describe( 'refresh()', () => {
it( 'should be enabled when selected element is an image', () => {
setModelData( model, '[<imageBlock src="foo/bar.jpg"></imageBlock>]' );

expect( command.isEnabled ).to.equal( true );
} );

it( 'should not enabled when selected element is not an image', () => {
setModelData( model, '[<paragraph>Foo</paragraph>]' );

expect( command.isEnabled ).to.equal( false );
} );

it( 'should store element src value', () => {
setModelData( model, '[<imageBlock src="foo/bar.jpg"></imageBlock>]' );

const element = model.document.selection.getSelectedElement();

expect( element.getAttribute( 'src' ) ).to.equal( command.value );
} );
} );
} );

0 comments on commit bf96e14

Please sign in to comment.