| Server IP : 54.94.228.101 / Your IP : 172.28.20.13 Web Server : Apache System : Linux ip-172-28-29-189 6.5.0-1014-aws #14~22.04.1-Ubuntu SMP Thu Feb 15 15:27:06 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.2.34-43+ubuntu22.04.1+deb.sury.org+1 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/html/vinumday2_0/public/plugins/@ckeditor/ckeditor5-ui/src/panel/sticky/ |
Upload File : |
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module ui/panel/sticky/stickypanelview
*/
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
import View from '../../view';
import Template from '../../template';
import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';
import '../../../theme/components/panel/stickypanel.css';
const toPx = toUnit( 'px' );
/**
* The sticky panel view class.
*/
export default class StickyPanelView extends View {
/**
* @inheritDoc
*/
constructor( locale ) {
super( locale );
const bind = this.bindTemplate;
/**
* Controls whether the sticky panel should be active.
*
* @readonly
* @observable
* @member {Boolean} #isActive
*/
this.set( 'isActive', false );
/**
* Controls whether the sticky panel is in the "sticky" state.
*
* @readonly
* @observable
* @member {Boolean} #isSticky
*/
this.set( 'isSticky', false );
/**
* The limiter element for the sticky panel instance. Its bounding rect limits
* the "stickyness" of the panel, i.e. when the panel reaches the bottom
* edge of the limiter, it becomes sticky to that edge and does not float
* off the limiter. It is mandatory for the panel to work properly and once
* set, it cannot be changed.
*
* @readonly
* @observable
* @member {HTMLElement} #limiterElement
*/
this.set( 'limiterElement', null );
/**
* The offset from the bottom edge of {@link #limiterElement}
* which stops the panel from stickying any further to prevent limiter's content
* from being completely covered.
*
* @readonly
* @observable
* @default 50
* @member {Number} #limiterBottomOffset
*/
this.set( 'limiterBottomOffset', 50 );
/**
* The offset from the top edge of the web browser's viewport which makes the
* panel become sticky. The default value is `0`, which means the panel becomes
* sticky when it's upper edge touches the top of the page viewport.
*
* This attribute is useful when the web page has UI elements positioned to the top
* either using `position: fixed` or `position: sticky`, which would cover the
* sticky panel or vice–versa (depending on the `z-index` hierarchy).
*
* @readonly
* @observable
* @default 0
* @member {Number} #viewportTopOffset
*/
this.set( 'viewportTopOffset', 0 );
/**
* Controls the `margin-left` CSS style of the panel.
*
* @protected
* @readonly
* @observable
* @member {String} #_marginLeft
*/
this.set( '_marginLeft', null );
/**
* Set `true` if the sticky panel reached the bottom edge of the
* {@link #limiterElement}.
*
* @protected
* @readonly
* @observable
* @member {Boolean} #_isStickyToTheLimiter
*/
this.set( '_isStickyToTheLimiter', false );
/**
* Set `true` if the sticky panel uses the {@link #viewportTopOffset},
* i.e. not {@link #_isStickyToTheLimiter} and the {@link #viewportTopOffset}
* is not `0`.
*
* @protected
* @readonly
* @observable
* @member {Boolean} #_hasViewportTopOffset
*/
this.set( '_hasViewportTopOffset', false );
/**
* Collection of the child views which creates balloon panel contents.
*
* @readonly
* @member {module:ui/viewcollection~ViewCollection}
*/
this.content = this.createCollection();
/**
* The DOM bounding client rect of the {@link module:ui/view~View#element} of the panel.
*
* @protected
* @member {Object} #_panelRect
*/
/**
* The DOM bounding client rect of the {@link #limiterElement}
* of the panel.
*
* @protected
* @member {Object} #_limiterRect
*/
/**
* A dummy element which visually fills the space as long as the
* actual panel is sticky. It prevents flickering of the UI.
*
* @protected
* @property {HTMLElement}
*/
this._contentPanelPlaceholder = new Template( {
tag: 'div',
attributes: {
class: [
'ck',
'ck-sticky-panel__placeholder'
],
style: {
display: bind.to( 'isSticky', isSticky => isSticky ? 'block' : 'none' ),
height: bind.to( 'isSticky', isSticky => {
return isSticky ? toPx( this._panelRect.height ) : null;
} )
}
}
} ).render();
/**
* The panel which accepts children into {@link #content} collection.
* Also an element which is positioned when {@link #isSticky}.
*
* @protected
* @property {HTMLElement}
*/
this._contentPanel = new Template( {
tag: 'div',
attributes: {
class: [
'ck',
'ck-sticky-panel__content',
// Toggle class of the panel when "sticky" state changes in the view.
bind.if( 'isSticky', 'ck-sticky-panel__content_sticky' ),
bind.if( '_isStickyToTheLimiter', 'ck-sticky-panel__content_sticky_bottom-limit' )
],
style: {
width: bind.to( 'isSticky', isSticky => {
return isSticky ? toPx( this._contentPanelPlaceholder.getBoundingClientRect().width ) : null;
} ),
top: bind.to( '_hasViewportTopOffset', _hasViewportTopOffset => {
return _hasViewportTopOffset ? toPx( this.viewportTopOffset ) : null;
} ),
bottom: bind.to( '_isStickyToTheLimiter', _isStickyToTheLimiter => {
return _isStickyToTheLimiter ? toPx( this.limiterBottomOffset ) : null;
} ),
marginLeft: bind.to( '_marginLeft' )
}
},
children: this.content
} ).render();
this.setTemplate( {
tag: 'div',
attributes: {
class: [
'ck',
'ck-sticky-panel'
]
},
children: [
this._contentPanelPlaceholder,
this._contentPanel
]
} );
}
/**
* @inheritDoc
*/
render() {
super.render();
// Check if the panel should go into the sticky state immediately.
this._checkIfShouldBeSticky();
// Update sticky state of the panel as the window is being scrolled.
this.listenTo( global.window, 'scroll', () => {
this._checkIfShouldBeSticky();
} );
// Synchronize with `model.isActive` because sticking an inactive panel is pointless.
this.listenTo( this, 'change:isActive', () => {
this._checkIfShouldBeSticky();
} );
}
/**
* Analyzes the environment to decide whether the panel should
* be sticky or not.
*
* @protected
*/
_checkIfShouldBeSticky() {
const panelRect = this._panelRect = this._contentPanel.getBoundingClientRect();
let limiterRect;
if ( !this.limiterElement ) {
this.isSticky = false;
} else {
limiterRect = this._limiterRect = this.limiterElement.getBoundingClientRect();
// The panel must be active to become sticky.
this.isSticky = this.isActive &&
// The limiter's top edge must be beyond the upper edge of the visible viewport (+the viewportTopOffset).
limiterRect.top < this.viewportTopOffset &&
// The model#limiterElement's height mustn't be smaller than the panel's height and model#limiterBottomOffset.
// There's no point in entering the sticky mode if the model#limiterElement is very, very small, because
// it would immediately set model#_isStickyToTheLimiter true and, given model#limiterBottomOffset, the panel
// would be positioned before the model#limiterElement.
this._panelRect.height + this.limiterBottomOffset < limiterRect.height;
}
// Stick the panel to the top edge of the viewport simulating CSS position:sticky.
// TODO: Possibly replaced by CSS in the future http://caniuse.com/#feat=css-sticky
if ( this.isSticky ) {
this._isStickyToTheLimiter =
limiterRect.bottom < panelRect.height + this.limiterBottomOffset + this.viewportTopOffset;
this._hasViewportTopOffset = !this._isStickyToTheLimiter && !!this.viewportTopOffset;
this._marginLeft = this._isStickyToTheLimiter ? null : toPx( -global.window.scrollX );
}
// Detach the panel from the top edge of the viewport.
else {
this._isStickyToTheLimiter = false;
this._hasViewportTopOffset = false;
this._marginLeft = null;
}
}
}