UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

463 lines (459 loc) • 18 kB
/** * DevExtreme (cjs/__internal/core/widget/dom_component.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 _short = require("../../../common/core/events/short"); var _config = _interopRequireDefault(require("../../../core/config")); var _element = require("../../../core/element"); var _element_data = require("../../../core/element_data"); var _errors = _interopRequireDefault(require("../../../core/errors")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _common = require("../../../core/utils/common"); var _extend = require("../../../core/utils/extend"); var _iterator = require("../../../core/utils/iterator"); var _public_component = require("../../../core/utils/public_component"); var _resize_callbacks = _interopRequireDefault(require("../../../core/utils/resize_callbacks")); var _shadow_dom = require("../../../core/utils/shadow_dom"); var _type = require("../../../core/utils/type"); var _window = require("../../../core/utils/window"); var _license_validation = _interopRequireWildcard(require("../../core/license/license_validation")); var _m_template_manager = _interopRequireDefault(require("../../core/m_template_manager")); var _m_common = require("../../core/utils/m_common"); var _component = require("./component"); 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 } } class DOMComponent extends _component.Component { static getInstance(element) { return (0, _public_component.getInstanceByElement)((0, _renderer.default)(element), this) } static defaultOptions(rule) { this._classCustomRules = Object.hasOwnProperty.bind(this)("_classCustomRules") && this._classCustomRules ? this._classCustomRules : []; this._classCustomRules.push(rule) } _getDefaultOptions() { return (0, _extend.extend)(super._getDefaultOptions(), { width: void 0, height: void 0, rtlEnabled: (0, _config.default)().rtlEnabled, elementAttr: {}, disabled: false, integrationOptions: {} }, this._useTemplates() ? _m_template_manager.default.TemplateManager.createDefaultOptions() : {}) } ctor(element, options) { this._customClass = null; this._createElement(element); (0, _public_component.attachInstanceToElement)(this._$element, this, this._dispose); super.ctor(options); const validationAlreadyPerformed = (0, _license_validation.peekValidationPerformed)(); _license_validation.default.validateLicense((0, _config.default)().licenseKey); if (!validationAlreadyPerformed && (0, _license_validation.peekValidationPerformed)()) { (0, _config.default)({ licenseKey: "" }) } _m_common.uiLayerInitialized.resolve() } _createElement(element) { this._$element = (0, _renderer.default)(element) } _getSynchronizableOptionsForCreateComponent() { return ["rtlEnabled", "disabled", "templatesRenderAsynchronously"] } _checkFunctionValueDeprecation(optionNames) { if (!this.option("_ignoreFunctionValueDeprecation")) { optionNames.forEach((optionName => { if ((0, _type.isFunction)(this.option(optionName))) { _errors.default.log("W0017", optionName) } })) } } _visibilityChanged(value) {} _dimensionChanged() {} _init() { super._init(); this._checkFunctionValueDeprecation(["width", "height", "maxHeight", "maxWidth", "minHeight", "minWidth", "popupHeight", "popupWidth"]); this._attachWindowResizeCallback(); this._initTemplateManager() } _setOptionsByDevice(instanceCustomRules) { super._setOptionsByDevice([].concat(this.constructor._classCustomRules || [], instanceCustomRules || [])) } _isInitialOptionValue(name) { const isCustomOption = this.constructor._classCustomRules && Object.prototype.hasOwnProperty.call(this._convertRulesToOptions(this.constructor._classCustomRules), name); return !isCustomOption && super._isInitialOptionValue(name) } _attachWindowResizeCallback() { if (this._isDimensionChangeSupported()) { const windowResizeCallBack = this._windowResizeCallBack = this._dimensionChanged.bind(this); _resize_callbacks.default.add(windowResizeCallBack) } } _isDimensionChangeSupported() { return this._dimensionChanged !== DOMComponent.prototype._dimensionChanged } _renderComponent() { (0, _shadow_dom.addShadowDomStyles)(this.$element()); this._initMarkup(); (0, _window.hasWindow)() && this._render() } _initMarkup() { const { rtlEnabled: rtlEnabled } = this.option() || {}; this._renderElementAttributes(); this._toggleRTLDirection(rtlEnabled); this._renderVisibilityChange(); this._renderDimensions() } _render() { this._attachVisibilityChangeHandlers() } _renderElementAttributes() { const { elementAttr: elementAttr } = this.option() || {}; const attributes = (0, _extend.extend)({}, elementAttr); const classNames = attributes.class; delete attributes.class; this.$element().attr(attributes).removeClass(this._customClass).addClass(classNames); this._customClass = classNames } _renderVisibilityChange() { if (this._isDimensionChangeSupported()) { this._attachDimensionChangeHandlers() } if (this._isVisibilityChangeSupported()) { const $element = this.$element(); $element.addClass("dx-visibility-change-handler") } } _renderDimensions() { const $element = this.$element(); const element = $element.get(0); const width = this._getOptionValue("width", element); const height = this._getOptionValue("height", element); if (this._isCssUpdateRequired(element, height, width)) { $element.css({ width: null === width ? "" : width, height: null === height ? "" : height }) } } _isCssUpdateRequired(element, height, width) { return !!((0, _type.isDefined)(width) || (0, _type.isDefined)(height) || element.style.width || element.style.height) } _attachDimensionChangeHandlers() { const $el = this.$element(); const namespace = `${this.NAME}VisibilityChange`; _short.resize.off($el, { namespace: namespace }); _short.resize.on($el, (() => this._dimensionChanged()), { namespace: namespace }) } _attachVisibilityChangeHandlers() { if (this._isVisibilityChangeSupported()) { const $el = this.$element(); const namespace = `${this.NAME}VisibilityChange`; this._isHidden = !this._isVisible(); _short.visibility.off($el, { namespace: namespace }); _short.visibility.on($el, (() => this._checkVisibilityChanged("shown")), (() => this._checkVisibilityChanged("hiding")), { namespace: namespace }) } } _isVisible() { const $element = this.$element(); return $element.is(":visible") } _checkVisibilityChanged(action) { const isVisible = this._isVisible(); if (isVisible) { if ("hiding" === action && !this._isHidden) { this._visibilityChanged(false); this._isHidden = true } else if ("shown" === action && this._isHidden) { this._isHidden = false; this._visibilityChanged(true) } } } _isVisibilityChangeSupported() { return this._visibilityChanged !== DOMComponent.prototype._visibilityChanged && (0, _window.hasWindow)() } _clean() {} _modelByElement(element) { const { modelByElement: modelByElement } = this.option(); const $element = this.$element(); return modelByElement ? modelByElement($element) : void 0 } _invalidate() { if (this._isUpdateAllowed()) { throw _errors.default.Error("E0007") } this._requireRefresh = true } _refresh() { this._clean(); this._renderComponent() } _dispose() { this._templateManager && this._templateManager.dispose(); super._dispose(); this._clean(); this._detachWindowResizeCallback() } _detachWindowResizeCallback() { if (this._isDimensionChangeSupported()) { _resize_callbacks.default.remove(this._windowResizeCallBack) } } _toggleRTLDirection(rtl) { const $element = this.$element(); $element.toggleClass("dx-rtl", rtl) } _createComponent(element, component, componentConfiguration) { const configuration = componentConfiguration ?? {}; const synchronizableOptions = (0, _common.grep)(this._getSynchronizableOptionsForCreateComponent(), (value => !(value in configuration))); const { integrationOptions: integrationOptions } = this.option(); let { nestedComponentOptions: nestedComponentOptions } = this.option(); nestedComponentOptions = nestedComponentOptions ?? _common.noop; const nestedComponentConfig = (0, _extend.extend)({ integrationOptions: integrationOptions }, nestedComponentOptions(this)); synchronizableOptions.forEach((optionName => nestedComponentConfig[optionName] = this.option(optionName))); this._extendConfig(configuration, nestedComponentConfig); let instance; if ((0, _type.isString)(component)) { const $element = (0, _renderer.default)(element)[component](configuration); instance = $element[component]("instance") } else if (element) { instance = component.getInstance(element); if (instance) { instance.option(configuration) } else { instance = new component(element, configuration) } } if (instance) { const optionChangedHandler = _ref => { let { name: name, value: value } = _ref; if (synchronizableOptions.includes(name)) { instance.option(name, value) } }; this.on("optionChanged", optionChangedHandler); instance.on("disposing", (() => this.off("optionChanged", optionChangedHandler))) } return instance } _extendConfig(configuration, extendConfig) { (0, _iterator.each)(extendConfig, ((key, value) => { !Object.prototype.hasOwnProperty.call(configuration, key) && (configuration[key] = value) })) } _defaultActionConfig() { const $element = this.$element(); const context = this._modelByElement($element); return (0, _extend.extend)(super._defaultActionConfig(), { context: context }) } _defaultActionArgs() { const $element = this.$element(); const model = this._modelByElement($element); const element = this.element(); return (0, _extend.extend)(super._defaultActionArgs(), { element: element, model: model }) } _optionChanged(args) { const { name: name } = args; switch (name) { case "width": case "height": this._renderDimensions(); break; case "rtlEnabled": this._invalidate(); break; case "elementAttr": this._renderElementAttributes(); break; case "disabled": case "integrationOptions": break; default: super._optionChanged(args) } } _removeAttributes(element) { const attrs = element.attributes; for (let i = attrs.length - 1; i >= 0; i--) { const attr = attrs[i]; if (attr) { const { name: name } = attr; if (!name.indexOf("aria-") || -1 !== name.indexOf("dx-") || "role" === name || "style" === name || "tabindex" === name) { element.removeAttribute(name) } } } } _removeClasses(element) { element.className = element.className.split(" ").filter((cssClass => 0 !== cssClass.lastIndexOf("dx-", 0))).join(" ") } _updateDOMComponent(renderRequired) { if (renderRequired) { this._renderComponent() } else if (this._requireRefresh) { this._requireRefresh = false; this._refresh() } } endUpdate() { const renderRequired = this._isInitializingRequired(); super.endUpdate(); this._isUpdateAllowed() && this._updateDOMComponent(renderRequired) } $element() { return this._$element } element() { const $element = this.$element(); return (0, _element.getPublicElement)($element) } dispose() { const element = this.$element().get(0); (0, _element_data.cleanDataRecursive)(element, true); element.textContent = ""; this._removeAttributes(element); this._removeClasses(element) } resetOption(optionName) { super.resetOption(optionName); if ("width" === optionName || "height" === optionName) { const initialOption = this.initialOption(optionName); !(0, _type.isDefined)(initialOption) && this.$element().css(optionName, "") } } _getAnonymousTemplateName() { return } _initTemplateManager() { if (this._templateManager || !this._useTemplates()) { return } const { integrationOptions: integrationOptions = {} } = this.option(); const { createTemplate: createTemplate } = integrationOptions; this._templateManager = new _m_template_manager.default.TemplateManager(createTemplate, this._getAnonymousTemplateName()); this._initTemplates(); return } _initTemplates() { const { templates: templates, anonymousTemplateMeta: anonymousTemplateMeta } = this._templateManager.extractTemplates(this.$element()); const anonymousTemplate = this.option(`integrationOptions.templates.${anonymousTemplateMeta.name}`); templates.forEach((_ref2 => { let { name: name, template: template } = _ref2; this._options.silent(`integrationOptions.templates.${name}`, template) })); if (anonymousTemplateMeta.name && !anonymousTemplate) { this._options.silent(`integrationOptions.templates.${anonymousTemplateMeta.name}`, anonymousTemplateMeta.template); this._options.silent("_hasAnonymousTemplateContent", true) } } _getTemplateByOption(optionName) { return this._getTemplate(this.option(optionName)) } _getTemplate(templateSource) { const templates = this.option("integrationOptions.templates"); const isAsyncTemplate = this.option("templatesRenderAsynchronously"); const skipTemplates = this.option("integrationOptions.skipTemplates"); return this._templateManager.getTemplate(templateSource, templates, { isAsyncTemplate: isAsyncTemplate, skipTemplates: skipTemplates }, this) } _saveTemplate(name, template) { this._setOptionWithoutOptionChange(`integrationOptions.templates.${name}`, this._templateManager._createTemplate(template)) } _useTemplates() { return true } } var _default = exports.default = DOMComponent;