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

Allowed BalloonPanelView limiter as a Function.

Aleksander Nowodzinski 8 лет назад
Родитель
Сommit
5ad922ff44

+ 28 - 12
packages/ckeditor5-ui/src/panel/balloon/balloonpanelview.js

@@ -253,15 +253,8 @@ export default class BalloonPanelView extends View {
 	_startPinning( options ) {
 		this.attachTo( options );
 
-		const limiter = options.limiter || defaultLimiterElement;
-		let targetElement = null;
-
-		// We need to take HTMLElement related to the target if it is possible.
-		if ( isElement( options.target ) ) {
-			targetElement = options.target;
-		} else if ( isRange( options.target ) ) {
-			targetElement = options.target.commonAncestorContainer;
-		}
+		const targetElement = getDomElement( options.target );
+		const limiterElement = getDomElement( options.limiter ) || defaultLimiterElement;
 
 		// Then we need to listen on scroll event of eny element in the document.
 		this.listenTo( global.document, 'scroll', ( evt, domEvt ) => {
@@ -271,10 +264,11 @@ export default class BalloonPanelView extends View {
 			const isWithinScrollTarget = targetElement && scrollTarget.contains( targetElement );
 
 			// The position needs to be updated if the positioning limiter is within the scrolled element.
-			const isLimiterWithinScrollTarget = scrollTarget.contains( limiter );
+			const isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains( limiterElement );
 
-			// The positioning target can be a Rect, object etc.. There's no way to optimize the listener then.
-			if ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement ) {
+			// The positioning target and/or limiter can be a Rect, object etc..
+			// There's no way to optimize the listener then.
+			if ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement ) {
 				this.attachTo( options );
 			}
 		}, { useCapture: true } );
@@ -296,6 +290,28 @@ export default class BalloonPanelView extends View {
 	}
 }
 
+// Returns the DOM element for given object or null, if there's none,
+// e.g. when passed object is a Rect instance or so.
+//
+// @private
+// @param {*} object
+// @returns {HTMLElement|null}
+function getDomElement( object ) {
+	if ( isElement( object ) ) {
+		return object;
+	}
+
+	if ( isRange( object ) ) {
+		return object.commonAncestorContainer;
+	}
+
+	if ( typeof object == 'function' ) {
+		return getDomElement( object() );
+	}
+
+	return null;
+}
+
 /**
  * A horizontal offset of the arrow tip from the edge of the balloon. Controlled by CSS.
  *

+ 16 - 0
packages/ckeditor5-ui/src/selectionrootobtainer.js

@@ -0,0 +1,16 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module ui/selectionrootobtainer
+ */
+
+export default function selectionRootObtainer( editor ) {
+	return () => {
+		const viewDocument = editor.editing.view;
+
+		return viewDocument.domConverter.mapViewToDom( viewDocument.selection.editableElement.root );
+	};
+}

+ 7 - 4
packages/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js

@@ -41,12 +41,14 @@ export default class ContextualToolbar extends Plugin {
 	 * @inheritDoc
 	 */
 	init() {
+		const editor = this.editor;
+
 		/**
 		 * The toolbar view displayed in the balloon.
 		 *
 		 * @member {module:ui/toolbar/toolbarview~ToolbarView}
 		 */
-		this.toolbarView = new ToolbarView( this.editor.locale );
+		this.toolbarView = new ToolbarView( editor.locale );
 
 		Template.extend( this.toolbarView.template, {
 			attributes: {
@@ -63,7 +65,7 @@ export default class ContextualToolbar extends Plugin {
 		 * @private
 		 * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}
 		 */
-		this._balloon = this.editor.plugins.get( ContextualBalloon );
+		this._balloon = editor.plugins.get( ContextualBalloon );
 
 		/**
 		 * Fires {@link #event:_selectionChangeDebounced} event using `lodash#debounce`.
@@ -196,7 +198,8 @@ export default class ContextualToolbar extends Plugin {
 	 * @returns {module:utils/dom/position~Options}
 	 */
 	_getBalloonPositionData() {
-		const editingView = this.editor.editing.view;
+		const editor = this.editor;
+		const editingView = editor.editing.view;
 
 		// Get direction of the selection.
 		const isBackward = editingView.selection.isBackward;
@@ -213,7 +216,7 @@ export default class ContextualToolbar extends Plugin {
 				// Select the proper range rect depending on the direction of the selection.
 				return rangeRects[ isBackward ? 0 : rangeRects.length - 1 ];
 			},
-			limiter: this.editor.ui.view.editable.element,
+			limiter: editor.config.get( 'ui.balloonLimiter' ),
 			positions: getBalloonPositions( isBackward )
 		};
 	}