Преглед изворни кода

Fixed: The toolbar should float over the editable if there is not enough space to display it above it. Closes #10.

Aleksander Nowodzinski пре 8 година
родитељ
комит
0eb836f234

+ 51 - 27
packages/ckeditor5-editor-inline/src/inlineeditoruiview.js

@@ -84,35 +84,43 @@ export default class InlineEditorUIView extends EditorUIView {
 	 *
 	 * The positioning functions are as follows:
 	 *
-	 * * South east:
+	 * * West:
 	 *
+	 *		[ Panel ]
 	 *		+------------------+
 	 *		| #editableElement |
 	 *		+------------------+
-	 *		           [ Panel ]
 	 *
-	 * * South west:
+	 *  	+------------------+
+	 *		| #editableElement |
+	 *		|[ Panel ]         |
+	 *		|                  |
+	 *		+------------------+
 	 *
 	 *		+------------------+
 	 *		| #editableElement |
 	 *		+------------------+
 	 *		[ Panel ]
 	 *
-	 * * North east:
+	 * * East:
 	 *
 	 *		           [ Panel ]
 	 *		+------------------+
 	 *		| #editableElement |
 	 *		+------------------+
 	 *
+	 *  	+------------------+
+	 *		| #editableElement |
+	 *		|         [ Panel ]|
+	 *		|                  |
+	 *		+------------------+
 	 *
-	 * * North west:
-	 *
-	 *		[ Panel ]
 	 *		+------------------+
 	 *		| #editableElement |
 	 *		+------------------+
+	 *		           [ Panel ]
 	 *
+	 * @readonly
 	 * @type {module:utils/dom/position~Options#positions}
 	 */
 	get panelPositions() {
@@ -126,24 +134,40 @@ export default class InlineEditorUIView extends EditorUIView {
 // @private
 // @type {module:utils/dom/position~Options#positions}
 const panelPositions = [
-	( editableRect, panelRect ) => ( {
-		top: editableRect.top - panelRect.height,
-		left: editableRect.left,
-		name: 'toolbar_nw'
-	} ),
-	( editableRect ) => ( {
-		top: editableRect.bottom,
-		left: editableRect.left,
-		name: 'toolbar_sw'
-	} ),
-	( editableRect, panelRect ) => ( {
-		top: editableRect.top - panelRect.height,
-		left: editableRect.left + editableRect.width - panelRect.width,
-		name: 'toolbar_ne'
-	} ),
-	( editableRect, panelRect ) => ( {
-		top: editableRect.bottom,
-		left: editableRect.left + editableRect.width - panelRect.width,
-		name: 'toolbar_se'
-	} )
+	( editableRect, panelRect ) => {
+		return {
+			top: getPanelPositionTop( editableRect, panelRect ),
+			left: editableRect.left,
+			name: 'toolbar_west'
+		};
+	},
+	( editableRect, panelRect ) => {
+		return {
+			top: getPanelPositionTop( editableRect, panelRect ),
+			left: editableRect.left + editableRect.width - panelRect.width,
+			name: 'toolbar_east'
+		};
+	}
 ];
+
+// Determines panel top position for
+// {@link module:editor-inline/inlineeditoruiview~InlineEditableUIView#panelPositions}
+//
+// @private
+// @param {module:utils/dom/rect~Rect} editableRect Rect of the
+// {@link module:editor-inline/inlineeditoruiview~InlineEditableUIView#editableElement}.
+// @param {module:utils/dom/rect~Rect} panelRect Rect of the
+// {@link module:editor-inline/inlineeditoruiview~InlineEditableUIView#panel}.
+function getPanelPositionTop( editableRect, panelRect ) {
+	let top;
+
+	if ( editableRect.top > panelRect.height ) {
+		top = editableRect.top - panelRect.height;
+	} else if ( editableRect.bottom > panelRect.height ) {
+		top = 0;
+	} else {
+		top = editableRect.bottom;
+	}
+
+	return top;
+}

+ 71 - 24
packages/ckeditor5-editor-inline/tests/inlineeditoruiview.js

@@ -94,7 +94,7 @@ describe( 'InlineEditorUIView', () => {
 	} );
 
 	describe( 'panelPositions', () => {
-		it( 'returns the right positions in the right order', () => {
+		it( 'returns the positions in the right order', () => {
 			const positions = view.panelPositions;
 			const editableRect = {
 				top: 100,
@@ -105,39 +105,86 @@ describe( 'InlineEditorUIView', () => {
 				height: 100
 			};
 			const panelRect = {
-				top: 0,
-				bottom: 0,
-				left: 0,
-				right: 0,
 				width: 50,
 				height: 50
 			};
 
-			expect( positions ).to.have.length( 4 );
+			expect( positions ).to.have.length( 2 );
+			expect( positions[ 0 ]( editableRect, panelRect ).name ).to.equal( 'toolbar_west' );
+			expect( positions[ 1 ]( editableRect, panelRect ).name ).to.equal( 'toolbar_east' );
+		} );
 
-			expect( positions[ 0 ]( editableRect, panelRect ) ).to.deep.equal( {
-				name: 'toolbar_nw',
-				left: 100,
-				top: 50
-			} );
+		describe( 'west', () => {
+			testTopPositions( 0, 100 );
+		} );
 
-			expect( positions[ 1 ]( editableRect, panelRect ) ).to.deep.equal( {
-				name: 'toolbar_sw',
-				left: 100,
-				top: 200
+		describe( 'east', () => {
+			testTopPositions( 1, 150 );
+		} );
+
+		function testTopPositions( positionIndex, expectedLeft ) {
+			it( 'positions the panel above editable when there\'s enough space', () => {
+				const position = view.panelPositions[ positionIndex ];
+				const editableRect = {
+					top: 100, // !
+					bottom: 200,
+					left: 100,
+					right: 100,
+					width: 100,
+					height: 100
+				};
+				const panelRect = {
+					width: 50,
+					height: 99 // !
+				};
+
+				const { top, left } = position( editableRect, panelRect );
+
+				expect( top ).to.equal( 1 );
+				expect( left ).to.equal( expectedLeft );
 			} );
 
-			expect( positions[ 2 ]( editableRect, panelRect ) ).to.deep.equal( {
-				name: 'toolbar_ne',
-				left: 150,
-				top: 50
+			it( 'positions the panel over the editable when there\'s not enough space above', () => {
+				const position = view.panelPositions[ positionIndex ];
+				const editableRect = {
+					top: 99, // !
+					bottom: 199,
+					left: 100,
+					right: 100,
+					width: 100,
+					height: 100
+				};
+				const panelRect = {
+					width: 50,
+					height: 100 // !
+				};
+
+				const { top, left } = position( editableRect, panelRect );
+
+				expect( top ).to.equal( 0 );
+				expect( left ).to.equal( expectedLeft );
 			} );
 
-			expect( positions[ 3 ]( editableRect, panelRect ) ).to.deep.equal( {
-				name: 'toolbar_se',
-				left: 150,
-				top: 200
+			it( 'positions the panel below the editable when there\'s not enough space above/over', () => {
+				const position = view.panelPositions[ positionIndex ];
+				const editableRect = {
+					top: 0,
+					bottom: 99,  // !
+					left: 100,
+					right: 100,
+					width: 100,
+					height: 99
+				};
+				const panelRect = {
+					width: 50,
+					height: 100 // !
+				};
+
+				const { top, left } = position( editableRect, panelRect );
+
+				expect( top ).to.equal( 99 );
+				expect( left ).to.equal( expectedLeft );
 			} );
-		} );
+		}
 	} );
 } );