Przeglądaj źródła

Implemented UI utils for the Image package.

Aleksander Nowodzinski 8 lat temu
rodzic
commit
ec5cb7408c

+ 51 - 0
packages/ckeditor5-image/src/image/ui/utils.js

@@ -0,0 +1,51 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module image/image/ui/utils
+ */
+
+import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';
+import { isImageWidget } from '../utils';
+
+/**
+ * A helper utility which positions the
+ * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} instance
+ * with respect to the image in the editor's content, if one is selected.
+ *
+ * @param {module:core/editor~Editor} editor Editor instance.
+ */
+export function repositionContextualBalloon( editor ) {
+	const editingView = editor.editing.view;
+	const balloon = editor.plugins.get( 'ContextualBalloon' );
+	const selectedElement = editingView.selection.getSelectedElement();
+
+	if ( selectedElement && isImageWidget( selectedElement ) ) {
+		const position = getBalloonPositionData( editor );
+
+		balloon.updatePosition( position );
+	}
+}
+
+/**
+ * Returns the positioning options that control the geometry of the
+ * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}, with respect
+ * to the selected element in the editor content.
+ *
+ * @param {module:core/editor~Editor} editor Editor instance.
+ * @returns {module:utils/dom/position~Options}
+ */
+export function getBalloonPositionData( editor ) {
+	const editingView = editor.editing.view;
+	const defaultPositions = BalloonPanelView.defaultPositions;
+
+	return {
+		target: editingView.domConverter.viewToDom( editingView.selection.getSelectedElement() ),
+		positions: [
+			defaultPositions.northArrowSouth,
+			defaultPositions.southArrowNorth
+		]
+	};
+}

+ 93 - 0
packages/ckeditor5-image/tests/image/ui/utils.js

@@ -0,0 +1,93 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+import Image from '../../src/image';
+import global from '@ckeditor/ckeditor5-utils/src/dom/global';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import View from '@ckeditor/ckeditor5-ui/src/view';
+import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';
+import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';
+import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import { repositionContextualBalloon, getBalloonPositionData } from '../../src/image/ui/utils';
+
+describe( 'Utils', () => {
+	let editor, doc, editingView, balloon, editorElement;
+
+	beforeEach( () => {
+		editorElement = global.document.createElement( 'div' );
+		global.document.body.appendChild( editorElement );
+
+		return ClassicEditor.create( editorElement, {
+			plugins: [ Image, Paragraph, ContextualBalloon ]
+		} )
+		.then( newEditor => {
+			editor = newEditor;
+			doc = editor.document;
+			editingView = editor.editing.view;
+			balloon = editor.plugins.get( 'ContextualBalloon' );
+		} );
+	} );
+
+	afterEach( () => {
+		editorElement.remove();
+
+		return editor.destroy();
+	} );
+
+	describe( 'repositionContextualBalloon', () => {
+		it( 'should re-position the ContextualBalloon when the image is selected', () => {
+			const spy = sinon.spy( balloon, 'updatePosition' );
+			const defaultPositions = BalloonPanelView.defaultPositions;
+			const view = new View();
+
+			view.element = global.document.createElement( 'div' );
+
+			balloon.add( {
+				view,
+				position: {
+					target: global.document.body
+				}
+			} );
+
+			setData( doc, '[<image src=""></image>]' );
+			repositionContextualBalloon( editor );
+
+			sinon.assert.calledWithExactly( spy, {
+				target: editingView.domConverter.viewToDom( editingView.selection.getSelectedElement() ),
+				positions: [
+					defaultPositions.northArrowSouth,
+					defaultPositions.southArrowNorth
+				]
+			} );
+		} );
+
+		it( 'should not engage with no image is selected', () => {
+			const spy = sinon.spy( balloon, 'updatePosition' );
+
+			setData( doc, '<paragraph>foo</paragraph>' );
+
+			repositionContextualBalloon( editor );
+			sinon.assert.notCalled( spy );
+		} );
+	} );
+
+	describe( 'getBalloonPositionData', () => {
+		it( 'returns the position data', () => {
+			const defaultPositions = BalloonPanelView.defaultPositions;
+
+			setData( doc, '[<image src=""></image>]' );
+			const data = getBalloonPositionData( editor );
+
+			expect( data ).to.deep.equal( {
+				target: editingView.domConverter.viewToDom( editingView.selection.getSelectedElement() ),
+				positions: [
+					defaultPositions.northArrowSouth,
+					defaultPositions.southArrowNorth
+				]
+			} );
+		} );
+	} );
+} );