UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

393 lines (392 loc) • 13.4 kB
/** * DevExtreme (esm/__internal/grids/grid_core/modules.js) * Version: 22.1.9 * Build date: Tue Apr 18 2023 * * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import $ from "../../../core/renderer"; import Class from "../../../core/class"; import Callbacks from "../../../core/utils/callbacks"; import { grep } from "../../../core/utils/common"; import { isFunction } from "../../../core/utils/type"; import { each } from "../../../core/utils/iterator"; import messageLocalization from "../../../localization/message"; import { hasWindow } from "../../../core/utils/window"; import errors from "../../../ui/widget/ui.errors"; const WIDGET_WITH_LEGACY_CONTAINER_NAME = "dxDataGrid"; const ModuleItem = Class.inherit({ _endUpdateCore() {}, ctor(component) { const that = this; that._updateLockCount = 0; that.component = component; that._actions = {}; that._actionConfigs = {}; each(this.callbackNames() || [], (function(index, name) { const flags = that.callbackFlags(name) || {}; flags.unique = true; flags.syncStrategy = true; that[this] = Callbacks(flags) })) }, init() {}, callbackNames() {}, callbackFlags() {}, publicMethods() {}, beginUpdate() { this._updateLockCount++ }, endUpdate() { if (this._updateLockCount > 0) { this._updateLockCount--; if (!this._updateLockCount) { this._endUpdateCore() } } }, option(name) { const { component: component } = this; const optionCache = component._optionCache; if (1 === arguments.length && optionCache) { if (!(name in optionCache)) { optionCache[name] = component.option(name) } return optionCache[name] } return component.option.apply(component, arguments) }, _silentOption(name, value) { const { component: component } = this; const optionCache = component._optionCache; if (optionCache) { optionCache[name] = value } return component._setOptionWithoutOptionChange(name, value) }, localize(name) { const optionCache = this.component._optionCache; if (optionCache) { if (!(name in optionCache)) { optionCache[name] = messageLocalization.format(name) } return optionCache[name] } return messageLocalization.format(name) }, on() { return this.component.on.apply(this.component, arguments) }, off() { return this.component.off.apply(this.component, arguments) }, optionChanged(args) { if (args.name in this._actions) { this.createAction(args.name, this._actionConfigs[args.name]); args.handled = true } }, getAction(actionName) { return this._actions[actionName] }, setAria(name, value, $target) { const target = $target.get(0); const prefix = "role" !== name && "id" !== name ? "aria-" : ""; if (target.setAttribute) { target.setAttribute(prefix + name, value) } else { $target.attr(prefix + name, value) } }, _createComponent() { return this.component._createComponent.apply(this.component, arguments) }, getController(name) { return this.component._controllers[name] }, createAction(actionName, config) { if (isFunction(actionName)) { const action = this.component._createAction(actionName.bind(this), config); return function(e) { action({ event: e }) } } this._actions[actionName] = this.component._createActionByOption(actionName, config); this._actionConfigs[actionName] = config }, executeAction(actionName, options) { const action = this._actions[actionName]; return action && action(options) }, dispose() { const that = this; each(that.callbackNames() || [], (function() { that[this].empty() })) }, addWidgetPrefix(className) { const componentName = this.component.NAME; return `dx-${componentName.slice(2).toLowerCase()}${className?"-"+className:""}` }, getWidgetContainerClass() { const containerName = "dxDataGrid" === this.component.NAME ? null : "container"; return this.addWidgetPrefix(containerName) }, elementIsInsideGrid($element) { const $gridElement = $element.closest("." + this.getWidgetContainerClass()).parent(); return $gridElement.is(this.component.$element()) } }); const Controller = ModuleItem; const ViewController = Controller.inherit({ getView(name) { return this.component._views[name] }, getViews() { return this.component._views } }); const View = ModuleItem.inherit({ _isReady() { return this.component.isReady() }, _endUpdateCore() { this.callBase(); if (!this._isReady() && this._requireReady) { this._requireRender = false; this.component._requireResize = false } if (this._requireRender) { this._requireRender = false; this.render(this._$parent) } }, _invalidate(requireResize, requireReady) { this._requireRender = true; this.component._requireResize = hasWindow() && (this.component._requireResize || requireResize); this._requireReady = this._requireReady || requireReady }, _renderCore() {}, _resizeCore() {}, _parentElement() { return this._$parent }, ctor(component) { this.callBase(component); this.renderCompleted = Callbacks(); this.resizeCompleted = Callbacks() }, element() { return this._$element }, getElementHeight() { const $element = this.element(); if (!$element) { return 0 } const marginTop = parseFloat($element.css("marginTop")) || 0; const marginBottom = parseFloat($element.css("marginBottom")) || 0; const { offsetHeight: offsetHeight } = $element.get(0); return offsetHeight + marginTop + marginBottom }, isVisible: () => true, getTemplate(name) { return this.component._getTemplate(name) }, render($parent, options) { let $element = this._$element; const isVisible = this.isVisible(); if (!$element && !$parent) { return } this._requireReady = false; if (!$element) { $element = this._$element = $("<div>").appendTo($parent); this._$parent = $parent } $element.toggleClass("dx-hidden", !isVisible); if (isVisible) { this.component._optionCache = {}; const deferred = this._renderCore(options); this.component._optionCache = void 0; if (deferred) { deferred.done(() => { this.renderCompleted.fire(options) }) } else { this.renderCompleted.fire(options) } } }, resize() { this.isResizing = true; this._resizeCore(); this.resizeCompleted.fire(); this.isResizing = false }, focus(preventScroll) { this.element().get(0).focus({ preventScroll: preventScroll }) } }); const MODULES_ORDER_MAX_INDEX = 1e6; const processModules = function(that, componentClass) { const { modules: modules } = componentClass; const { modulesOrder: modulesOrder } = componentClass; const controllerTypes = componentClass.controllerTypes || {}; const viewTypes = componentClass.viewTypes || {}; if (!componentClass.controllerTypes) { if (modulesOrder) { modules.sort((module1, module2) => { let orderIndex1 = modulesOrder.indexOf(module1.name); let orderIndex2 = modulesOrder.indexOf(module2.name); if (orderIndex1 < 0) { orderIndex1 = 1e6 } if (orderIndex2 < 0) { orderIndex2 = 1e6 } return orderIndex1 - orderIndex2 }) } each(modules, (function() { const { controllers: controllers } = this; const moduleName = this.name; const { views: views } = this; controllers && each(controllers, (name, type) => { if (controllerTypes[name]) { throw errors.Error("E1001", moduleName, name) } else if (!(type && type.subclassOf && type.subclassOf(Controller))) { type.subclassOf(Controller); throw errors.Error("E1002", moduleName, name) } controllerTypes[name] = type }); views && each(views, (name, type) => { if (viewTypes[name]) { throw errors.Error("E1003", moduleName, name) } else if (!(type && type.subclassOf && type.subclassOf(View))) { throw errors.Error("E1004", moduleName, name) } viewTypes[name] = type }) })); each(modules, (function() { const { extenders: extenders } = this; if (extenders) { extenders.controllers && each(extenders.controllers, (name, extender) => { if (controllerTypes[name]) { controllerTypes[name] = controllerTypes[name].inherit(extender) } }); extenders.views && each(extenders.views, (name, extender) => { if (viewTypes[name]) { viewTypes[name] = viewTypes[name].inherit(extender) } }) } })); componentClass.controllerTypes = controllerTypes; componentClass.viewTypes = viewTypes } const createModuleItems = function(moduleTypes) { const moduleItems = {}; each(moduleTypes, (name, moduleType) => { const moduleItem = new moduleType(that); moduleItem.name = name; ! function(that, name, moduleItem) { const publicMethods = moduleItem.publicMethods(); if (publicMethods) { each(publicMethods, (index, methodName) => { if (moduleItem[methodName]) { if (!that[methodName]) { that[methodName] = function() { return moduleItem[methodName].apply(moduleItem, arguments) } } else { throw errors.Error("E1005", methodName) } } else { throw errors.Error("E1006", name, methodName) } }) } }(that, name, moduleItem); moduleItems[name] = moduleItem }); return moduleItems }; that._controllers = createModuleItems(controllerTypes); that._views = createModuleItems(viewTypes) }; const callModuleItemsMethod = function(that, methodName, args) { args = args || []; if (that._controllers) { each(that._controllers, (function() { this[methodName] && this[methodName].apply(this, args) })) } if (that._views) { each(that._views, (function() { this[methodName] && this[methodName].apply(this, args) })) } }; export default { modules: [], View: View, ViewController: ViewController, Controller: Controller, registerModule(name, module) { const { modules: modules } = this; for (let i = 0; i < modules.length; i++) { if (modules[i].name === name) { return } } module.name = name; modules.push(module); delete this.controllerTypes; delete this.viewTypes }, registerModulesOrder(moduleNames) { this.modulesOrder = moduleNames }, unregisterModule(name) { this.modules = grep(this.modules, module => module.name !== name); delete this.controllerTypes; delete this.viewTypes }, processModules: processModules, callModuleItemsMethod: callModuleItemsMethod };