UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,209 lines (1,204 loc) • 48.3 kB
/** * DevExtreme (cjs/__internal/ui/overlay/overlay.js) * Version: 25.1.5 * Build date: Wed Sep 03 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.OVERLAY_CONTENT_CLASS = void 0; var _animation = require("../../../common/core/animation"); var _hide_callback = require("../../../common/core/environment/hide_callback"); var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _drag = require("../../../common/core/events/drag"); var _pointer = _interopRequireDefault(require("../../../common/core/events/pointer")); var _short = require("../../../common/core/events/short"); var _utils = require("../../../common/core/events/utils"); var _visibility_change = require("../../../common/core/events/visibility_change"); var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator")); var _devices = _interopRequireDefault(require("../../../core/devices")); var _dom_adapter = _interopRequireDefault(require("../../../core/dom_adapter")); var _element = require("../../../core/element"); var _errors = _interopRequireDefault(require("../../../core/errors")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _empty_template = require("../../../core/templates/empty_template"); var _browser = _interopRequireDefault(require("../../../core/utils/browser")); var _common = require("../../../core/utils/common"); var _deferred = require("../../../core/utils/deferred"); var _extend = require("../../../core/utils/extend"); var _iterator = require("../../../core/utils/iterator"); var _ready_callbacks = _interopRequireDefault(require("../../../core/utils/ready_callbacks")); var _size = require("../../../core/utils/size"); var _type = require("../../../core/utils/type"); var _view_port = require("../../../core/utils/view_port"); var _ui = _interopRequireDefault(require("../../../ui/widget/ui.errors")); var _m_dom = _interopRequireDefault(require("../../core/utils/m_dom")); var _m_selectors = _interopRequireDefault(require("../../core/utils/m_selectors")); var _m_window = _interopRequireDefault(require("../../core/utils/m_window")); var _widget = _interopRequireDefault(require("../../core/widget/widget")); var _overlay_position_controller = require("../../ui/overlay/overlay_position_controller"); var zIndexPool = _interopRequireWildcard(require("../../ui/overlay/z_index")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) { return null } var r = new WeakMap, t = new WeakMap; return (_getRequireWildcardCache = function(e) { return e ? t : r })(e) } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) { return e } if (null === e || "object" != typeof e && "function" != typeof e) { return { default: e } } var t = _getRequireWildcardCache(r); if (t && t.has(e)) { return t.get(e) } var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) { if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u] } } return n.default = e, t && t.set(e, n), n } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const ready = _ready_callbacks.default.add; const window = _m_window.default.getWindow(); const viewPortChanged = _view_port.changeCallback; const OVERLAY_STACK = []; const ANONYMOUS_TEMPLATE_NAME = "content"; const TAB_KEY = "tab"; const OVERLAY_CLASS = "dx-overlay"; const OVERLAY_WRAPPER_CLASS = "dx-overlay-wrapper"; const OVERLAY_CONTENT_CLASS = exports.OVERLAY_CONTENT_CLASS = "dx-overlay-content"; const OVERLAY_SHADER_CLASS = "dx-overlay-shader"; const INNER_OVERLAY_CLASS = "dx-inner-overlay"; const INVISIBLE_STATE_CLASS = "dx-state-invisible"; const RTL_DIRECTION_CLASS = "dx-rtl"; const PREVENT_SAFARI_SCROLLING_CLASS = "dx-prevent-safari-scrolling"; ready((() => { _events_engine.default.subscribeGlobal(_dom_adapter.default.getDocument(), _pointer.default.down, (e => { for (let i = OVERLAY_STACK.length - 1; i >= 0; i -= 1) { var _OVERLAY_STACK$i$_pro, _OVERLAY_STACK$i; if (!(null !== (_OVERLAY_STACK$i$_pro = (_OVERLAY_STACK$i = OVERLAY_STACK[i])._proxiedDocumentDownHandler) && void 0 !== _OVERLAY_STACK$i$_pro && _OVERLAY_STACK$i$_pro.call(_OVERLAY_STACK$i, e))) { return } } })) })); class Overlay extends _widget.default { _supportedKeys() { return _extends({}, super._supportedKeys(), { escape() { this.hide() } }) } _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { activeStateEnabled: false, visible: false, deferRendering: true, shading: true, shadingColor: "", wrapperAttr: {}, position: _extends({}, _overlay_position_controller.OVERLAY_POSITION_ALIASES.center), width: "80vw", minWidth: null, maxWidth: null, height: "80vh", minHeight: null, maxHeight: null, animation: { show: { type: "pop", duration: 300, from: { scale: .55 } }, hide: { type: "pop", duration: 300, from: { opacity: 1, scale: 1 }, to: { opacity: 0, scale: .55 } } }, hideOnOutsideClick: false, onShowing: null, onShown: null, onHiding: null, onHidden: null, contentTemplate: "content", innerOverlay: false, restorePosition: true, hideOnParentScroll: false, preventScrollEvents: true, onPositioned: null, propagateOutsideClick: false, ignoreChildEvents: true, _checkParentVisibility: true, _fixWrapperPosition: false, _loopFocus: false, _ignorePreventScrollEventsDeprecation: false, hideTopOverlayHandler: () => { this.hide() } }) } _defaultOptionsRules() { const rules = [...super._defaultOptionsRules(), { device: () => !_m_window.default.hasWindow(), options: { width: null, height: null, animation: null, _checkParentVisibility: false } }]; return rules } _setOptionsByReference() { super._setOptionsByReference(); this._optionsByReference = _extends({}, this._optionsByReference, { animation: true }) } $wrapper() { return this._$wrapper } _eventBindingTarget() { return this._$content } ctor(element, options) { super.ctor(element, options); if (options) { if ("preventScrollEvents" in options && !options._ignorePreventScrollEventsDeprecation) { this._logDeprecatedPreventScrollEventsInfo() } } } _logDeprecatedPreventScrollEventsInfo() { this._logDeprecatedOptionWarning("preventScrollEvents", { since: "23.1", message: "If you enable this option, end-users may experience scrolling issues." }) } _init() { super._init(); this._initActions(); this._initHideOnOutsideClickHandler(); this._initTabTerminatorHandler(); this._customWrapperClass = null; this._$wrapper = (0, _renderer.default)("<div>").addClass("dx-overlay-wrapper"); this._$content = (0, _renderer.default)("<div>").addClass(OVERLAY_CONTENT_CLASS); this._initInnerOverlayClass(); const $element = this.$element(); $element.addClass("dx-overlay"); this._$wrapper.attr("data-bind", "dxControlsDescendantBindings: true"); this._toggleViewPortSubscription(true); const { hideTopOverlayHandler: hideTopOverlayHandler } = this.option(); this._initHideTopOverlayHandler(hideTopOverlayHandler); this._parentsScrollSubscriptionInfo = { handler: e => { this._hideOnParentsScrollHandler(e) } }; this.warnPositionAsFunction() } warnPositionAsFunction() { const { position: position } = this.option(); if ((0, _type.isFunction)(position)) { _errors.default.log("W0018") } } _initInnerOverlayClass() { const { innerOverlay: innerOverlay } = this.option(); this._$content.toggleClass("dx-inner-overlay", innerOverlay) } _initHideTopOverlayHandler(handler) { if (handler) { this._hideTopOverlayHandler = handler } } _getActionsList() { return ["onShowing", "onShown", "onHiding", "onHidden", "onPositioned", "onVisualPositionChanged"] } _initActions() { this._actions = {}; const actions = this._getActionsList(); (0, _iterator.each)(actions, ((_, action) => { if (this._actions) { this._actions[action] = this._createActionByOption(action, { excludeValidators: ["disabled", "readOnly"] }) || _common.noop } })) } _initHideOnOutsideClickHandler() { this._proxiedDocumentDownHandler = e => this._documentDownHandler(e) } _initMarkup() { super._initMarkup(); this._renderWrapperAttributes(); this._initPositionController() } _documentDownHandler(e) { if (this._showAnimationProcessing) { this._stopAnimation() } const { target: target } = e; const $target = (0, _renderer.default)(target); const isTargetDocument = _m_dom.default.contains(window.document, target); const isAttachedTarget = (0, _renderer.default)(window.document).is($target) || isTargetDocument; const isInnerOverlay = (0, _renderer.default)($target).closest(".dx-inner-overlay").length; const isTargetContent = this._$content.is($target); const isTargetInContent = _m_dom.default.contains(this._$content.get(0), target); const isOutsideClick = isAttachedTarget && !isInnerOverlay && !(isTargetContent || isTargetInContent); if (isOutsideClick && this._shouldHideOnOutsideClick(e)) { this._outsideClickHandler(e) } const { propagateOutsideClick: propagateOutsideClick } = this.option(); return Boolean(propagateOutsideClick) } _shouldHideOnOutsideClick(e) { const { hideOnOutsideClick: hideOnOutsideClick } = this.option(); if ((0, _type.isFunction)(hideOnOutsideClick)) { return hideOnOutsideClick(e) } return Boolean(hideOnOutsideClick) } _outsideClickHandler(e) { const { shading: shading } = this.option(); if (shading) { e.preventDefault() } this.hide() } _getAnonymousTemplateName() { return "content" } _initTemplates() { this._templateManager.addDefaultTemplates({ content: new _empty_template.EmptyTemplate }); super._initTemplates() } _isTopOverlay() { const overlayStack = this._overlayStack(); for (let i = overlayStack.length - 1; i >= 0; i -= 1) { const tabbableElements = overlayStack[i]._findTabbableBounds(); if (tabbableElements.$first || tabbableElements.$last) { return overlayStack[i] === this } } return false } _overlayStack() { return OVERLAY_STACK } _zIndexInitValue() { return Overlay.baseZIndex() } _toggleViewPortSubscription(toggle) { if (this._viewPortChangeHandle) { viewPortChanged.remove(this._viewPortChangeHandle) } if (toggle) { this._viewPortChangeHandle = () => { this._viewPortChangeHandler() }; viewPortChanged.add(this._viewPortChangeHandle) } } _viewPortChangeHandler() { const { container: container } = this.option(); this._positionController.updateContainer(container); this._refresh() } _renderWrapperAttributes() { const { wrapperAttr: wrapperAttr } = this.option(); const attributes = _extends({}, wrapperAttr); const classNames = attributes.class; delete attributes.class; const $wrapper = this.$wrapper(); $wrapper.attr(attributes); if (this._customWrapperClass) { $wrapper.removeClass(this._customWrapperClass) } $wrapper.addClass(classNames); this._customWrapperClass = classNames } _renderVisibilityAnimate(visible) { this._stopAnimation(); return visible ? this._show() : this._hide() } _getAnimationConfig() { return this._getOptionValue("animation", this) ?? {} } _toggleBodyScroll(enabled) {} _animateShowing() { const animation = this._getAnimationConfig(); const showAnimation = this._normalizeAnimation(animation.show, "to"); const startShowAnimation = (null === showAnimation || void 0 === showAnimation ? void 0 : showAnimation.start) ?? _common.noop; const completeShowAnimation = (null === showAnimation || void 0 === showAnimation ? void 0 : showAnimation.complete) ?? _common.noop; this._animate(showAnimation, ((element, config) => { var _this$_actions, _this$_actions$onShow; if (this._isAnimationPaused) { return } const { focusStateEnabled: focusStateEnabled } = this.option(); if (focusStateEnabled) { _events_engine.default.trigger(this._focusTarget(), "focus") } completeShowAnimation.call(this, element, config); this._showAnimationProcessing = false; this._isHidden = false; null === (_this$_actions = this._actions) || void 0 === _this$_actions || null === (_this$_actions$onShow = _this$_actions.onShown) || void 0 === _this$_actions$onShow || _this$_actions$onShow.call(_this$_actions); this._toggleSafariScrolling(); this._showingDeferred.resolve() }), ((element, config) => { if (this._isAnimationPaused) { return } startShowAnimation.call(this, element, config); this._showAnimationProcessing = true })) } _processShowingHidingCancel(cancelArg, applyFunction, cancelFunction) { if ((0, _type.isPromise)(cancelArg)) { cancelArg.then((shouldCancel => { if (shouldCancel) { cancelFunction() } else { applyFunction() } })).catch((() => applyFunction())) } else if (cancelArg) { cancelFunction() } else { applyFunction() } } _show() { this._showingDeferred = (0, _deferred.Deferred)(); this._parentHidden = this._isParentHidden(); this._showingDeferred.done((() => { delete this._parentHidden })); if (this._parentHidden) { this._isHidden = true; return this._showingDeferred.resolve() } if (this._currentVisible) { return (0, _deferred.Deferred)().resolve().promise() } this._currentVisible = true; if (this._isHidingActionCanceled) { delete this._isHidingActionCanceled; this._showingDeferred.reject() } else { const show = () => { var _this$_actions2, _this$_actions2$onSho; this._stopAnimation(); const { enableBodyScroll: enableBodyScroll } = this.option(); this._toggleBodyScroll(enableBodyScroll); this._toggleVisibility(true); this._$content.css("visibility", "hidden"); this._$content.toggleClass("dx-state-invisible", false); this._updateZIndexStackPosition(true); this._positionController.openingHandled(); this._renderContent(); const showingArgs = { cancel: false }; null === (_this$_actions2 = this._actions) || void 0 === _this$_actions2 || null === (_this$_actions2$onSho = _this$_actions2.onShowing) || void 0 === _this$_actions2$onSho || _this$_actions2$onSho.call(_this$_actions2, showingArgs); this._processShowingHidingCancel(showingArgs.cancel, (() => { this._$content.css("visibility", ""); this._renderVisibility(true); this._animateShowing() }), (() => { this._toggleVisibility(false); this._$content.css("visibility", ""); this._$content.toggleClass("dx-state-invisible", true); this._isShowingActionCanceled = true; this._moveFromContainer(); this._toggleBodyScroll(true); this.option("visible", false); this._showingDeferred.resolve() })) }; show() } return this._showingDeferred.promise() } _normalizeAnimation(showHideConfig, direction) { if (!showHideConfig) { return } const configuration = _extends({ type: "slide", skipElementInitialStyles: true }, showHideConfig); if ((0, _type.isObject)(configuration[direction])) { (0, _extend.extend)(configuration[direction], { position: this._positionController.position }) } return configuration } _animateHiding() { const animation = this._getAnimationConfig(); const hideAnimation = this._normalizeAnimation(animation.hide, "from"); const startHideAnimation = (null === hideAnimation || void 0 === hideAnimation ? void 0 : hideAnimation.start) ?? _common.noop; const completeHideAnimation = (null === hideAnimation || void 0 === hideAnimation ? void 0 : hideAnimation.complete) ?? _common.noop; this._animate(hideAnimation, ((element, config) => { var _this$_actions3, _this$_actions3$onHid; this._$content.css("pointerEvents", ""); this._renderVisibility(false); completeHideAnimation.call(this, element, config); this._hideAnimationProcessing = false; null === (_this$_actions3 = this._actions) || void 0 === _this$_actions3 || null === (_this$_actions3$onHid = _this$_actions3.onHidden) || void 0 === _this$_actions3$onHid || _this$_actions3$onHid.call(_this$_actions3); this._hidingDeferred.resolve() }), ((element, config) => { this._$content.css("pointerEvents", "none"); startHideAnimation.call(this, element, config); this._hideAnimationProcessing = true })) } _hide() { if (!this._currentVisible) { return (0, _deferred.Deferred)().resolve().promise() } this._currentVisible = false; this._hidingDeferred = (0, _deferred.Deferred)(); const hidingArgs = { cancel: false }; if (this._isShowingActionCanceled) { delete this._isShowingActionCanceled; this._hidingDeferred.reject() } else { var _this$_actions4, _this$_actions4$onHid; null === (_this$_actions4 = this._actions) || void 0 === _this$_actions4 || null === (_this$_actions4$onHid = _this$_actions4.onHiding) || void 0 === _this$_actions4$onHid || _this$_actions4$onHid.call(_this$_actions4, hidingArgs); this._toggleSafariScrolling(); this._toggleBodyScroll(true); const cancelHide = () => { this._isHidingActionCanceled = true; const { enableBodyScroll: enableBodyScroll } = this.option(); this._toggleBodyScroll(enableBodyScroll); this.option("visible", true); this._hidingDeferred.resolve() }; const applyHide = () => { this._forceFocusLost(); this._toggleShading(false); this._toggleSubscriptions(false); this._animateHiding() }; this._processShowingHidingCancel(hidingArgs.cancel, applyHide, cancelHide) } return this._hidingDeferred.promise() } _forceFocusLost() { const activeElement = _dom_adapter.default.getActiveElement(); const shouldResetActiveElement = !!this._$content.find(activeElement).length; if (shouldResetActiveElement) { _m_dom.default.resetActiveElement() } } _animate(animation, completeCallback, startCallback) { if (animation) { const actualStartCallback = startCallback ?? animation.start ?? _common.noop; const configuration = _extends({}, animation, { start: actualStartCallback, complete: completeCallback }); _animation.fx.animate(this._$content.get(0), configuration) } else { completeCallback() } } _stopAnimation() { _animation.fx.stop(this._$content.get(0), true) } _renderVisibility(visible) { if (visible && this._isParentHidden()) { return } this._currentVisible = visible; this._stopAnimation(); if (!visible) { (0, _visibility_change.triggerHidingEvent)(this._$content) } if (visible) { this._checkContainerExists(); this._moveToContainer(); this._renderGeometry(); (0, _visibility_change.triggerShownEvent)(this._$content); (0, _visibility_change.triggerResizeEvent)(this._$content) } else { this._toggleVisibility(visible); this._$content.toggleClass("dx-state-invisible", !visible); this._updateZIndexStackPosition(visible); this._moveFromContainer() } this._toggleShading(visible); this._toggleSubscriptions(visible) } _updateZIndexStackPosition(pushToStack) { const overlayStack = this._overlayStack(); const index = overlayStack.indexOf(this); if (pushToStack) { if (-1 === index) { this._zIndex = zIndexPool.create(this._zIndexInitValue()); overlayStack.push(this) } this._$wrapper.css("zIndex", this._zIndex); this._$content.css("zIndex", this._zIndex) } else if (-1 !== index) { overlayStack.splice(index, 1); zIndexPool.remove(this._zIndex) } } _toggleShading(visible) { const { shading: shading, shadingColor: shadingColor } = this.option(); this._$wrapper.toggleClass("dx-overlay-shader", visible && shading); this._$wrapper.css("backgroundColor", shading ? shadingColor ?? "" : ""); this._toggleTabTerminator(Boolean(visible && shading)) } _initTabTerminatorHandler() { this._proxiedTabTerminatorHandler = e => { this._tabKeyHandler(e) } } _toggleTabTerminator(enabled) { const { _loopFocus: _loopFocus } = this.option(); const eventName = (0, _utils.addNamespace)("keydown", this.NAME); if (_loopFocus || enabled) { _events_engine.default.on(_dom_adapter.default.getDocument(), eventName, this._proxiedTabTerminatorHandler) } else { this._destroyTabTerminator() } } _destroyTabTerminator() { const eventName = (0, _utils.addNamespace)("keydown", this.NAME); _events_engine.default.off(_dom_adapter.default.getDocument(), eventName, this._proxiedTabTerminatorHandler) } _findTabbableBounds() { const $elements = this._$wrapper.find("*"); const elementsCount = $elements.length - 1; let $first = null; let $last = null; for (let i = 0; i <= elementsCount; i += 1) { const $currentElement = $elements.eq(i); const $reverseElement = $elements.eq(elementsCount - i); if (!$first && $currentElement.is(_m_selectors.default.tabbable)) { $first = $currentElement } if (!$last && $reverseElement.is(_m_selectors.default.tabbable)) { $last = $reverseElement } if ($first && $last) { break } } return { $first: $first, $last: $last } } _tabKeyHandler(e) { if ("tab" !== (0, _utils.normalizeKeyName)(e) || !this._isTopOverlay()) { return } const wrapper = this._$wrapper.get(0); const activeElement = _dom_adapter.default.getActiveElement(wrapper); const { $first: $firstTabbable, $last: $lastTabbable } = this._findTabbableBounds(); const isTabOnLast = !e.shiftKey && activeElement === (null === $lastTabbable || void 0 === $lastTabbable ? void 0 : $lastTabbable.get(0)); const isShiftTabOnFirst = e.shiftKey && activeElement === (null === $firstTabbable || void 0 === $firstTabbable ? void 0 : $firstTabbable.get(0)); const isOutsideTarget = !_m_dom.default.contains(wrapper, activeElement); const shouldPreventDefault = isTabOnLast || isShiftTabOnFirst || isOutsideTarget; if (shouldPreventDefault) { e.preventDefault(); const $focusElement = e.shiftKey ? $lastTabbable : $firstTabbable; _events_engine.default.trigger($focusElement, "focusin"); _events_engine.default.trigger($focusElement, "focus") } } _toggleSubscriptions(enabled) { if (_m_window.default.hasWindow()) { this._toggleHideTopOverlayCallback(enabled); this._toggleHideOnParentsScrollSubscription(enabled) } } _toggleHideTopOverlayCallback(subscribe) { if (!this._hideTopOverlayHandler) { return } if (subscribe) { _hide_callback.hideCallback.add(this._hideTopOverlayHandler) } else { _hide_callback.hideCallback.remove(this._hideTopOverlayHandler) } } _toggleHideOnParentsScrollSubscription(needSubscribe) { const scrollEvent = (0, _utils.addNamespace)("scroll", this.NAME); const info = this._parentsScrollSubscriptionInfo ?? {}; const { prevTargets: prevTargets, handler: handler } = info; _events_engine.default.off(prevTargets, scrollEvent, handler); const { hideOnParentScroll: hideOnParentScroll } = this.option(); if (needSubscribe && hideOnParentScroll) { let $parents = this._getHideOnParentScrollTarget().parents(); if ("desktop" === _devices.default.real().deviceType) { $parents = $parents.add(window) } _events_engine.default.on($parents, scrollEvent, handler); this._parentsScrollSubscriptionInfo = _extends({}, info, { prevTargets: $parents }) } } _hideOnParentsScrollHandler(e) { let hideHandled = false; const { hideOnParentScroll: hideOnParentScroll } = this.option(); if ((0, _type.isFunction)(hideOnParentScroll)) { hideHandled = hideOnParentScroll(e) } if (!hideHandled && !this._showAnimationProcessing) { this.hide() } } _getHideOnParentScrollTarget() { const { _hideOnParentScrollTarget: _hideOnParentScrollTarget } = this.option(); const $hideOnParentScrollTarget = (0, _renderer.default)(_hideOnParentScrollTarget); if ($hideOnParentScrollTarget.length) { return $hideOnParentScrollTarget } return this._$wrapper } _render() { super._render(); this._appendContentToElement(); this._renderVisibilityAnimate(this._isVisible()) } _appendContentToElement() { if (!this._$content.parent().is(this.$element())) { this._$content.appendTo(this.$element()) } } _renderContent() { const { deferRendering: deferRendering } = this.option(); const shouldDeferRendering = !this._currentVisible && deferRendering; const isParentHidden = this._isVisible() && this._isParentHidden(); if (isParentHidden) { this._isHidden = true; return } if (this._contentAlreadyRendered || shouldDeferRendering) { return } this._contentAlreadyRendered = true; this._appendContentToElement(); super._renderContent() } _isParentHidden() { const { _checkParentVisibility: _checkParentVisibility } = this.option(); if (!_checkParentVisibility) { return false } if (void 0 !== this._parentHidden) { return this._parentHidden } const $parent = this.$element().parent(); if ($parent.is(":visible")) { return false } let isHidden = false; $parent.add($parent.parents()).each(((index, element) => { const $element = (0, _renderer.default)(element); if ("none" === $element.css("display")) { isHidden = true; return false } return })); return isHidden || !_dom_adapter.default.getBody().contains($parent.get(0)) } _renderContentImpl() { const { contentTemplate: contentTemplateOption } = this.option(); const whenContentRendered = (0, _deferred.Deferred)(); const contentTemplate = this._getTemplate(contentTemplateOption); const transclude = this._templateManager.anonymousTemplateName === contentTemplateOption; null === contentTemplate || void 0 === contentTemplate || contentTemplate.render({ container: (0, _element.getPublicElement)(this.$content()), noModel: true, transclude: transclude, onRendered: () => { whenContentRendered.resolve(); const { templatesRenderAsynchronously: templatesRenderAsynchronously } = this.option(); if (templatesRenderAsynchronously) { this._dimensionChanged() } } }); const { preventScrollEvents: preventScrollEvents } = this.option(); this._toggleWrapperScrollEventsSubscription(preventScrollEvents); whenContentRendered.done((() => { this._processContentRendering() })); return whenContentRendered.promise() } _processContentRendering() { if (this._isVisible()) { this._moveToContainer() } } _getPositionControllerConfig() { var _this$_actions5, _this$_actions6; const { container: container, visualContainer: visualContainer, restorePosition: restorePosition, _fixWrapperPosition: _fixWrapperPosition, _skipContentPositioning: _skipContentPositioning } = this.option(); const properties = { container: container, visualContainer: visualContainer, restorePosition: restorePosition, _fixWrapperPosition: _fixWrapperPosition, _skipContentPositioning: _skipContentPositioning, onPositioned: null === (_this$_actions5 = this._actions) || void 0 === _this$_actions5 ? void 0 : _this$_actions5.onPositioned, onVisualPositionChanged: null === (_this$_actions6 = this._actions) || void 0 === _this$_actions6 ? void 0 : _this$_actions6.onVisualPositionChanged }; const elements = { $root: this.$element(), $content: this._$content, $wrapper: this._$wrapper }; const positionControllerConfiguration = { properties: properties, elements: elements }; return positionControllerConfiguration } _initPositionController() { this._positionController = new _overlay_position_controller.OverlayPositionController(this._getPositionControllerConfig()) } _toggleWrapperScrollEventsSubscription(enabled) { const eventName = (0, _utils.addNamespace)(_drag.move, this.NAME); _events_engine.default.off(this._$wrapper, eventName); if (enabled) { const callback = e => { const { originalEvent: originalEvent } = e.originalEvent; const { type: type } = originalEvent ?? {}; const isWheel = "wheel" === type; const isMouseMove = "mousemove" === type; const isScrollByWheel = isWheel && (0, _utils.isCommandKeyPressed)(e); e._cancelPreventDefault = true; if (originalEvent && false !== e.cancelable && !(isMouseMove || isScrollByWheel)) { e.preventDefault() } }; const options = { validate: () => true, getDirection: () => "both", _toggleGestureCover(toggle) { if (!toggle) { this._toggleGestureCoverImpl(toggle) } }, _clearSelection: _common.noop, isNative: true }; _events_engine.default.on(this._$wrapper, eventName, options, callback) } } _moveFromContainer() { this._$content.appendTo(this.$element()); this._$wrapper.detach() } _checkContainerExists() { const $wrapperContainer = this._positionController.$container; if (void 0 === $wrapperContainer) { return } const containerExists = $wrapperContainer.length > 0; if (!containerExists) { _ui.default.log("W1021", this.NAME) } } _moveToContainer() { const $wrapperContainer = this._positionController.$container; if (void 0 !== $wrapperContainer) { this._$wrapper.appendTo($wrapperContainer) } this._$content.appendTo(this._$wrapper) } _renderGeometry() { if (this._isVisible() && _m_window.default.hasWindow()) { this._stopAnimation(); this._renderGeometryImpl() } } _renderGeometryImpl() { this._positionController.updatePosition(this._getOptionValue("position")); this._renderWrapper(); this._renderDimensions(); this._renderPosition() } _renderPosition(state) { this._positionController.positionContent() } _isAllWindowCovered() { var _this$_positionContro; const { shading: shading } = this.option(); const element = null === (_this$_positionContro = this._positionController.$visualContainer) || void 0 === _this$_positionContro ? void 0 : _this$_positionContro.get(0); return (0, _type.isWindow)(element) && Boolean(shading) } _toggleSafariScrolling() { const visible = this._isVisible(); const $body = (0, _renderer.default)(_dom_adapter.default.getBody()); const isIosSafari = "ios" === _devices.default.real().platform && _browser.default.safari; const isAllWindowCovered = this._isAllWindowCovered(); const isScrollingPrevented = $body.hasClass("dx-prevent-safari-scrolling"); const shouldPreventScrolling = !isScrollingPrevented && visible && isAllWindowCovered; const shouldEnableScrolling = isScrollingPrevented && (!visible || !isAllWindowCovered || this._disposed); if (isIosSafari) { if (shouldEnableScrolling) { $body.removeClass("dx-prevent-safari-scrolling"); window.scrollTo(0, this._cachedBodyScrollTop); this._cachedBodyScrollTop = void 0 } else if (shouldPreventScrolling) { this._cachedBodyScrollTop = window.pageYOffset; $body.addClass("dx-prevent-safari-scrolling") } } } _renderWrapper() { this._positionController.styleWrapperPosition(); this._renderWrapperDimensions(); this._positionController.positionWrapper() } _renderWrapperDimensions() { const { $visualContainer: $visualContainer } = this._positionController; const documentElement = _dom_adapter.default.getDocumentElement(); const isVisualContainerWindow = (0, _type.isWindow)(null === $visualContainer || void 0 === $visualContainer ? void 0 : $visualContainer.get(0)); const wrapperWidth = isVisualContainerWindow ? documentElement.clientWidth : (0, _size.getOuterWidth)($visualContainer); const wrapperHeight = isVisualContainerWindow ? window.innerHeight : (0, _size.getOuterHeight)($visualContainer); this._$wrapper.css({ width: wrapperWidth, height: wrapperHeight }) } _renderDimensions() { const content = this._$content.get(0); this._$content.css({ minWidth: this._getOptionValue("minWidth", content), maxWidth: this._getOptionValue("maxWidth", content), minHeight: this._getOptionValue("minHeight", content), maxHeight: this._getOptionValue("maxHeight", content), width: this._getOptionValue("width", content), height: this._getOptionValue("height", content) }) } _focusTarget() { return this._$content } _attachKeyboardEvents() { this._keyboardListenerId = _short.keyboard.on(this._$content, null, (options => this._keyboardHandler(options))) } _keyboardHandler(options, onlyChildProcessing) { const e = options.originalEvent; const $target = (0, _renderer.default)(e.target); const { ignoreChildEvents: ignoreChildEvents } = this.option(); if ($target.is(this._$content) || !ignoreChildEvents) { super._keyboardHandler(options, onlyChildProcessing) } } _isVisible() { const visible = this.option("visible"); return Boolean(visible) } _visibilityChanged(visible) { if (visible) { if (this._isVisible()) { this._renderVisibilityAnimate(visible) } } else { this._renderVisibilityAnimate(visible) } } _dimensionChanged() { this._renderGeometry() } _clean() { if (!this._contentAlreadyRendered) { this.$content().empty() } this._renderVisibility(false); this._cleanFocusState() } _dispose() { _animation.fx.stop(this._$content.get(0), false); this._toggleViewPortSubscription(false); this._toggleSubscriptions(false); this._updateZIndexStackPosition(false); this._actions = {}; this._parentsScrollSubscriptionInfo = void 0; super._dispose(); this._toggleSafariScrolling(); if (this._isVisible()) { zIndexPool.remove(this._zIndex) } this._$wrapper.remove(); this._$content.remove(); this._destroyTabTerminator() } _toggleRTLDirection(rtl) { this._$content.toggleClass("dx-rtl", rtl) } _optionChanged(args) { const { value: value, name: name } = args; if (this._getActionsList().includes(name)) { this._initActions(); return } switch (name) { case "animation": case "hideOnOutsideClick": case "propagateOutsideClick": break; case "_loopFocus": case "shading": this._toggleShading(this._isVisible()); this._toggleSafariScrolling(); break; case "shadingColor": this._toggleShading(this._isVisible()); break; case "width": case "height": case "minWidth": case "maxWidth": case "minHeight": case "maxHeight": this._renderGeometry(); break; case "position": { const { position: position } = this.option(); this._positionController.updatePosition(position); this._positionController.restorePositionOnNextRender(true); this._renderGeometry(); this._toggleSafariScrolling(); break } case "visible": this._renderVisibilityAnimate(Boolean(value)).done((() => { var _this$_animateDeferre; return null === (_this$_animateDeferre = this._animateDeferred) || void 0 === _this$_animateDeferre ? void 0 : _this$_animateDeferre.resolveWith(this) })).fail((() => { var _this$_animateDeferre2; return null === (_this$_animateDeferre2 = this._animateDeferred) || void 0 === _this$_animateDeferre2 ? void 0 : _this$_animateDeferre2.reject() })); break; case "container": this._positionController.updateContainer(value); this._invalidate(); this._toggleSafariScrolling(); break; case "visualContainer": this._positionController.updateVisualContainer(value); this._renderWrapper(); this._toggleSafariScrolling(); break; case "innerOverlay": this._initInnerOverlayClass(); break; case "deferRendering": case "contentTemplate": this._contentAlreadyRendered = false; this._clean(); this._invalidate(); break; case "hideTopOverlayHandler": this._toggleHideTopOverlayCallback(false); this._initHideTopOverlayHandler(value); this._toggleHideTopOverlayCallback(this._isVisible()); break; case "hideOnParentScroll": case "_hideOnParentScrollTarget": this._toggleHideOnParentsScrollSubscription(this._isVisible()); break; case "rtlEnabled": this._contentAlreadyRendered = false; super._optionChanged(args); break; case "_fixWrapperPosition": this._positionController.fixWrapperPosition = value; break; case "wrapperAttr": this._renderWrapperAttributes(); break; case "restorePosition": this._positionController.restorePosition = value; break; case "preventScrollEvents": this._logDeprecatedPreventScrollEventsInfo(); this._toggleWrapperScrollEventsSubscription(value); break; default: super._optionChanged(args) } } toggle(showing) { const visible = this._isVisible(); const isShowing = showing ?? !visible; const result = (0, _deferred.Deferred)(); if (isShowing === visible) { return result.resolveWith(this, [isShowing]).promise() } const animateDeferred = (0, _deferred.Deferred)(); this._animateDeferred = animateDeferred; this.option("visible", isShowing); animateDeferred.promise().done((() => { delete this._animateDeferred; result.resolveWith(this, [this._isVisible()]) })).fail((() => { delete this._animateDeferred; result.reject() })); return result.promise() } $content() { return this._$content } show() { return this.toggle(true) } hide() { return this.toggle(false) } content() { return (0, _element.getPublicElement)(this._$content) } repaint() { if (this._contentAlreadyRendered) { this._positionController.restorePositionOnNextRender(true); this._renderGeometry({ forceStopAnimation: true }); (0, _visibility_change.triggerResizeEvent)(this._$content) } else { super.repaint() } } static baseZIndex(zIndex) { return zIndexPool.base(zIndex) } }(0, _component_registrator.default)("dxOverlay", Overlay); var _default = exports.default = Overlay;