| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- /**
- * @module ui/balloonpanel/balloonpanelview
- */
- /* globals document */
- import View from '../view';
- import Template from '../template';
- import { getOptimalPosition } from '@ckeditor/ckeditor5-utils/src/dom/position';
- import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';
- const toPx = toUnit( 'px' );
- /**
- * The balloon panel view class.
- *
- * @extends module:ui/view~View
- */
- export default class BalloonPanelView extends View {
- /**
- * @inheritDoc
- */
- constructor( locale ) {
- super( locale );
- const bind = this.bindTemplate;
- /**
- * The absolute top position of the balloon panel in pixels.
- *
- * @observable
- * @default 0
- * @member {Number} #top
- */
- this.set( 'top', 0 );
- /**
- * The absolute left position of the balloon panel in pixels.
- *
- * @observable
- * @default 0
- * @member {Number} #left
- */
- this.set( 'left', 0 );
- /**
- * Balloon panel's current position. The position name is reflected in the CSS class set
- * to the balloon, i.e. `.ck-balloon-panel_arrow_se` for "se" position. The class
- * controls the minor aspects of the balloon's visual appearance like placement
- * of the "arrow". To support a new position, an additional CSS must be created.
- *
- * Default position names correspond with {@link #defaultPositions}.
- *
- * @observable
- * @default 'se'
- * @member {'se'|'sw'|'ne'|'nw'} #position
- */
- this.set( 'position', 'se' );
- /**
- * Controls whether the balloon panel is visible or not.
- *
- * @observable
- * @default false
- * @member {Boolean} #isVisible
- */
- this.set( 'isVisible', false );
- /**
- * Max width of the balloon panel, as in CSS.
- *
- * @observable
- * @member {Number} #maxWidth
- */
- /**
- * Collection of the child views which creates balloon panel contents.
- *
- * @readonly
- * @member {module:ui/viewcollection~ViewCollection}
- */
- this.content = this.createCollection();
- this.template = new Template( {
- tag: 'div',
- attributes: {
- class: [
- 'ck-balloon-panel',
- bind.to( 'position', ( value ) => `ck-balloon-panel_arrow_${ value }` ),
- bind.if( 'isVisible', 'ck-balloon-panel_visible' )
- ],
- style: {
- top: bind.to( 'top', toPx ),
- left: bind.to( 'left', toPx ),
- maxWidth: bind.to( 'maxWidth', toPx )
- },
- // Make this element `focusable` to be available for adding to FocusTracker.
- tabindex: -1
- },
- children: this.content
- } );
- }
- /**
- * Shows the balloon panel.
- *
- * See {@link #isVisible}.
- */
- show() {
- this.isVisible = true;
- }
- /**
- * Hides the balloon panel.
- *
- * See {@link #isVisible}.
- */
- hide() {
- this.isVisible = false;
- }
- /**
- * Attaches the balloon panel to a specified DOM element or range with a smart heuristics.
- *
- * See {@link @link module:utils/dom/position~getOptimalPosition}.
- *
- * TODO: More docs and examples.
- *
- * @param {module:utils/dom/position~Options} options Positioning options compatible with
- * {@link module:utils/dom/position~getOptimalPosition}. Default `positions` array is
- * {@link module:ui/balloonpanel/balloonpanelview~BalloonPanelView.defaultPositions}.
- */
- attachTo( options ) {
- this.show();
- const defaultPositions = BalloonPanelView.defaultPositions;
- const positionOptions = Object.assign( {}, {
- element: this.element,
- positions: [
- defaultPositions.se,
- defaultPositions.sw,
- defaultPositions.ne,
- defaultPositions.nw
- ],
- limiter: document.body,
- fitInViewport: true
- }, options );
- const { top, left, name: position } = getOptimalPosition( positionOptions );
- Object.assign( this, { top, left, position } );
- }
- }
- /**
- * A horizontal offset of the arrow tip from the edge of the balloon. Controlled by CSS.
- *
- * +-----|---------...
- * | |
- * | |
- * | |
- * | |
- * +--+ | +------...
- * \ | /
- * \|/
- * >|-----|<---------------- horizontal offset
- *
- * @default 30
- * @member {Number} module:ui/balloonpanel/balloonpanelview~BalloonPanelView.arrowHorizontalOffset
- */
- BalloonPanelView.arrowHorizontalOffset = 30;
- /**
- * A vertical offset of the arrow from the edge of the balloon. Controlled by CSS.
- *
- * +-------------...
- * |
- * |
- * | /-- vertical offset
- * | V
- * +--+ +-----... ---------
- * \ / |
- * \/ |
- * -------------------------------
- * ^
- *
- * @default 15
- * @member {Number} module:ui/balloonpanel/balloonpanelview~BalloonPanelView.arrowVerticalOffset
- */
- BalloonPanelView.arrowVerticalOffset = 15;
- /**
- * A default set of positioning functions used by the balloon panel view
- * when attaching using {@link #attachTo} method.
- *
- * The available positioning functions are as follows:
- *
- * * South east:
- *
- * [ Target ]
- * ^
- * +-----------------+
- * | Balloon |
- * +-----------------+
- *
- *
- * * South west:
- *
- * [ Target ]
- * ^
- * +-----------------+
- * | Balloon |
- * +-----------------+
- *
- *
- * * North east:
- *
- * +-----------------+
- * | Balloon |
- * +-----------------+
- * V
- * [ Target ]
- *
- *
- * * North west:
- *
- * +-----------------+
- * | Balloon |
- * +-----------------+
- * V
- * [ Target ]
- *
- * See {@link #attachTo}.
- *
- * Positioning functions must be compatible with {@link module:utils/dom/position~Position}.
- *
- * The name that position function returns will be reflected in balloon panel's class that
- * controls the placement of the "arrow". See {@link #position} to learn more.
- *
- * @member {Object} module:ui/balloonpanel/balloonpanelview~BalloonPanelView.defaultPositions
- */
- BalloonPanelView.defaultPositions = {
- se: ( targetRect ) => ( {
- top: targetRect.bottom + BalloonPanelView.arrowVerticalOffset,
- left: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,
- name: 'se'
- } ),
- sw: ( targetRect, balloonRect ) => ( {
- top: targetRect.bottom + BalloonPanelView.arrowVerticalOffset,
- left: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,
- name: 'sw'
- } ),
- ne: ( targetRect, balloonRect ) => ( {
- top: targetRect.top - balloonRect.height - BalloonPanelView.arrowVerticalOffset,
- left: targetRect.left + targetRect.width / 2 - BalloonPanelView.arrowHorizontalOffset,
- name: 'ne'
- } ),
- nw: ( targetRect, balloonRect ) => ( {
- top: targetRect.top - balloonRect.height - BalloonPanelView.arrowVerticalOffset,
- left: targetRect.left + targetRect.width / 2 - balloonRect.width + BalloonPanelView.arrowHorizontalOffset,
- name: 'nw'
- } )
- };
|