UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

257 lines (254 loc) • 10.1 kB
/** * DevExtreme (cjs/__internal/ui/m_defer_rendering.js) * Version: 24.2.6 * Build date: Mon Mar 17 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 = void 0; var _transition_executor = require("../../common/core/animation/transition_executor/transition_executor"); var _events_engine = _interopRequireDefault(require("../../common/core/events/core/events_engine")); var _visibility_change = require("../../common/core/events/visibility_change"); var _component_registrator = _interopRequireDefault(require("../../core/component_registrator")); var _dom_adapter = _interopRequireDefault(require("../../core/dom_adapter")); var _renderer = _interopRequireDefault(require("../../core/renderer")); var _common = require("../../core/utils/common"); var _deferred = require("../../core/utils/deferred"); var _iterator = require("../../core/utils/iterator"); var _position = require("../../core/utils/position"); var _type = require("../../core/utils/type"); var _window = require("../../core/utils/window"); var _load_indicator = _interopRequireDefault(require("../../ui/load_indicator")); var _widget = _interopRequireDefault(require("../core/widget/widget")); 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 window = (0, _window.getWindow)(); const WIDGET_CLASS = "dx-widget"; const DEFER_RENDERING_CLASS = "dx-deferrendering"; const PENDING_RENDERING_CLASS = "dx-pending-rendering"; const PENDING_RENDERING_MANUAL_CLASS = "dx-pending-rendering-manual"; const PENDING_RENDERING_ACTIVE_CLASS = "dx-pending-rendering-active"; const VISIBLE_WHILE_PENDING_RENDERING_CLASS = "dx-visible-while-pending-rendering"; const INVISIBLE_WHILE_PENDING_RENDERING_CLASS = "dx-invisible-while-pending-rendering"; const LOADINDICATOR_CONTAINER_CLASS = "dx-loadindicator-container"; const DEFER_RENDERING_LOADINDICATOR_CONTAINER_CLASS = "dx-deferrendering-loadindicator-container"; const DEFER_DEFER_RENDERING_LOAD_INDICATOR = "dx-deferrendering-load-indicator"; const ANONYMOUS_TEMPLATE_NAME = "content"; const ACTIONS = ["onRendered", "onShown"]; class DeferRendering extends _widget.default { _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { showLoadIndicator: false, onRendered: null, onShown: null }) } _getAnonymousTemplateName() { return "content" } _init() { this.transitionExecutor = new _transition_executor.TransitionExecutor; this._initElement(); this._initRender(); this._$initialContent = this.$element().clone().contents(); this._initActions(); super._init() } _initElement() { this.$element().addClass("dx-deferrendering") } _initRender() { const that = this; const $element = this.$element(); const renderWhen = this.option("renderWhen"); const doRender = () => that._renderDeferredContent(); if ((0, _type.isPromise)(renderWhen)) { (0, _deferred.fromPromise)(renderWhen).done(doRender) } else { $element.data("dx-render-delegate", doRender); if (void 0 === renderWhen) { $element.addClass("dx-pending-rendering-manual") } } } _initActions() { this._actions = {}; (0, _iterator.each)(ACTIONS, ((_, action) => { this._actions[action] = this._createActionByOption(action) || _common.noop })) } _initMarkup() { super._initMarkup(); if (!this._initContent) { this._initContent = this._renderContent; this._renderContent = () => {} } this._initContent() } _renderContentImpl() { this.$element().removeClass("dx-widget"); this.$element().append(this._$initialContent); this._setLoadingState() } _renderDeferredContent() { const that = this; const $element = this.$element(); const result = (0, _deferred.Deferred)(); $element.removeClass("dx-pending-rendering-manual"); $element.addClass("dx-pending-rendering-active"); this._abortRenderTask(); this._renderTask = (0, _common.executeAsync)((() => { that._renderImpl().done((() => { const shownArgs = { element: $element }; that._actions.onShown([shownArgs]); result.resolve(shownArgs) })).fail((function() { result.rejectWith(result, arguments) })) })); return result.promise() } _isElementInViewport(element) { const rect = (0, _position.getBoundingRect)(element); return rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || _dom_adapter.default.getDocumentElement().clientHeight) && rect.left <= (window.innerWidth || _dom_adapter.default.getDocumentElement().clientWidth) } _animate() { const that = this; const $element = this.$element(); const animation = (0, _window.hasWindow)() && this.option("animation"); const staggerItemSelector = this.option("staggerItemSelector"); let animatePromise; that.transitionExecutor.stop(); if (animation) { if (staggerItemSelector) { $element.find(staggerItemSelector).each((function() { if (that._isElementInViewport(this)) { that.transitionExecutor.enter((0, _renderer.default)(this), animation) } })) } else { that.transitionExecutor.enter($element, animation) } animatePromise = that.transitionExecutor.start() } else { animatePromise = (0, _deferred.Deferred)().resolve().promise() } return animatePromise } _renderImpl() { const $element = this.$element(); const renderedArgs = { element: $element }; const contentTemplate = this._getTemplate(this._templateManager.anonymousTemplateName); if (contentTemplate) { contentTemplate.render({ container: $element.empty(), noModel: true }) } this._setRenderedState(); _events_engine.default.trigger($element, "dxcontentrendered"); this._actions.onRendered([renderedArgs]); this._isRendered = true; return this._animate() } _setLoadingState() { const $element = this.$element(); const hasCustomLoadIndicator = !!$element.find(".dx-visible-while-pending-rendering").length; $element.addClass("dx-pending-rendering"); if (!hasCustomLoadIndicator) { $element.children().addClass("dx-invisible-while-pending-rendering") } if (this.option("showLoadIndicator")) { this._showLoadIndicator($element) } } _showLoadIndicator($container) { this._$loadIndicator = new _load_indicator.default((0, _renderer.default)("<div>"), { visible: true }).$element().addClass("dx-deferrendering-load-indicator"); (0, _renderer.default)("<div>").addClass("dx-loadindicator-container").addClass("dx-deferrendering-loadindicator-container").append(this._$loadIndicator).appendTo($container) } _setRenderedState() { const $element = this.$element(); if (this._$loadIndicator) { this._$loadIndicator.remove() } $element.removeClass("dx-pending-rendering"); $element.removeClass("dx-pending-rendering-active"); (0, _visibility_change.triggerShownEvent)($element.children()) } _optionChanged(args) { const { value: value } = args; const { previousValue: previousValue } = args; switch (args.name) { case "renderWhen": if (false === previousValue && true === value) { this._renderOrAnimate() } else if (true === previousValue && false === value) { this.transitionExecutor.stop(); this._setLoadingState() } break; case "showLoadIndicator": case "onRendered": case "onShown": break; default: super._optionChanged(args) } } _renderOrAnimate() { let result; if (this._isRendered) { this._setRenderedState(); result = this._animate() } else { result = this._renderDeferredContent() } return result } renderContent() { return this._renderOrAnimate() } _abortRenderTask() { if (this._renderTask) { this._renderTask.abort(); this._renderTask = void 0 } } _dispose() { this.transitionExecutor.stop(true); this._abortRenderTask(); this._actions = void 0; this._$initialContent = void 0; super._dispose() } }(0, _component_registrator.default)("dxDeferRendering", DeferRendering); var _default = exports.default = DeferRendering;