1/* eslint-disable */ 2this.BX = this.BX || {}; 3(function (exports, main_core, ui_designTokens, ui_fonts_opensans, main_core_events, ui_a11y, main_core_zIndexManager) { 4 'use strict'; 5 6 class PositionEvent extends main_core_events.BaseEvent { 7 #left; 8 #top; 9 get left() { 10 return this.#left; 11 } 12 set left(value) { 13 if (main_core.Type.isNumber(value)) { 14 this.#left = value; 15 } 16 } 17 get top() { 18 return this.#top; 19 } 20 set top(value) { 21 if (main_core.Type.isNumber(value)) { 22 this.#top = value; 23 } 24 } 25 } 26 27 /** 28 * @namespace {BX.Main.Popup} 29 */ 30 const CloseIconSize = Object.freeze({ 31 LARGE: 'large', 32 SMALL: 'small' 33 }); 34 35 /** 36 * @memberOf BX.Main.Popup 37 * @deprecated use BX.UI.Button 38 */ 39 let Button = /*#__PURE__*/function () { 40 function Button(params) { 41 babelHelpers.classCallCheck(this, Button); 42 this.popupWindow = null; 43 this.params = params || {}; 44 this.text = this.params.text || ''; 45 this.id = this.params.id || ''; 46 this.className = this.params.className || ''; 47 this.events = this.params.events || {}; 48 this.contextEvents = {}; 49 for (let eventName in this.events) { 50 if (main_core.Type.isFunction(this.events[eventName])) { 51 this.contextEvents[eventName] = this.events[eventName].bind(this); 52 } 53 } 54 this.buttonNode = main_core.Dom.create('button', { 55 props: { 56 className: 'popup-window-button' + (this.className.length > 0 ? ' ' + this.className : ''), 57 id: this.id 58 }, 59 attrs: { 60 tabindex: '0', 61 type: 'button' 62 }, 63 events: this.contextEvents, 64 text: this.text 65 }); 66 } 67 return babelHelpers.createClass(Button, [{ 68 key: "render", 69 value: function render() { 70 return this.buttonNode; 71 } 72 }, { 73 key: "getId", 74 value: function getId() { 75 return this.id; 76 } 77 }, { 78 key: "getContainer", 79 value: function getContainer() { 80 return this.buttonNode; 81 } 82 }, { 83 key: "getName", 84 value: function getName() { 85 return this.text; 86 } 87 }, { 88 key: "setName", 89 value: function setName(name) { 90 this.text = name || ''; 91 if (this.buttonNode) { 92 main_core.Dom.clean(this.buttonNode); 93 main_core.Dom.adjust(this.buttonNode, { 94 text: this.text 95 }); 96 } 97 } 98 }, { 99 key: "setClassName", 100 value: function setClassName(className) { 101 if (this.buttonNode) { 102 if (main_core.Type.isString(this.className) && this.className !== '') { 103 main_core.Dom.removeClass(this.buttonNode, this.className); 104 } 105 main_core.Dom.addClass(this.buttonNode, className); 106 } 107 this.className = className; 108 } 109 }, { 110 key: "addClassName", 111 value: function addClassName(className) { 112 if (this.buttonNode) { 113 main_core.Dom.addClass(this.buttonNode, className); 114 this.className = this.buttonNode.className; 115 } 116 } 117 }, { 118 key: "removeClassName", 119 value: function removeClassName(className) { 120 if (this.buttonNode) { 121 main_core.Dom.removeClass(this.buttonNode, className); 122 this.className = this.buttonNode.className; 123 } 124 } 125 }]); 126 }(); 127 128 var _Popup; 129 function _callSuper$1(t, o, e) { return o = babelHelpers.getPrototypeOf(o), babelHelpers.possibleConstructorReturn(t, _isNativeReflectConstruct$1() ? Reflect.construct(o, [], babelHelpers.getPrototypeOf(t).constructor) : o.apply(t, e)); } 130 function _isNativeReflectConstruct$1() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct$1 = function () { return !!t; })(); } 131 function _superPropGet(t, o, e, r) { var p = babelHelpers.get(babelHelpers.getPrototypeOf(t.prototype ), o, e); return "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } 132 function _classPrivateMethodInitSpec$1(e, a) { _checkPrivateRedeclaration$1(e, a), a.add(e); } 133 function _classPrivateFieldInitSpec$1(e, t, a) { _checkPrivateRedeclaration$1(e, t), t.set(e, a); } 134 function _checkPrivateRedeclaration$1(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } 135 function _classPrivateFieldGet$1(s, a) { return s.get(_assertClassBrand$1(s, a)); } 136 function _classPrivateFieldSet$1(s, a, r) { return s.set(_assertClassBrand$1(s, a), r), r; } 137 function _assertClassBrand$1(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } 138 const aliases$1 = { 139 onPopupWindowInit: { 140 namespace: 'BX.Main.Popup', 141 eventName: 'onInit' 142 }, 143 onPopupWindowIsInitialized: { 144 namespace: 'BX.Main.Popup', 145 eventName: 'onAfterInit' 146 }, 147 onPopupFirstShow: { 148 namespace: 'BX.Main.Popup', 149 eventName: 'onFirstShow' 150 }, 151 onPopupShow: { 152 namespace: 'BX.Main.Popup', 153 eventName: 'onShow' 154 }, 155 onAfterPopupShow: { 156 namespace: 'BX.Main.Popup', 157 eventName: 'onAfterShow' 158 }, 159 onPopupClose: { 160 namespace: 'BX.Main.Popup', 161 eventName: 'onClose' 162 }, 163 onPopupAfterClose: { 164 namespace: 'BX.Main.Popup', 165 eventName: 'onAfterClose' 166 }, 167 onPopupDestroy: { 168 namespace: 'BX.Main.Popup', 169 eventName: 'onDestroy' 170 }, 171 onPopupFullscreenLeave: { 172 namespace: 'BX.Main.Popup', 173 eventName: 'onFullscreenLeave' 174 }, 175 onPopupFullscreenEnter: { 176 namespace: 'BX.Main.Popup', 177 eventName: 'onFullscreenEnter' 178 }, 179 onPopupDragStart: { 180 namespace: 'BX.Main.Popup', 181 eventName: 'onDragStart' 182 }, 183 onPopupDrag: { 184 namespace: 'BX.Main.Popup', 185 eventName: 'onDrag' 186 }, 187 onPopupDragEnd: { 188 namespace: 'BX.Main.Popup', 189 eventName: 'onDragEnd' 190 }, 191 onPopupResizeStart: { 192 namespace: 'BX.Main.Popup', 193 eventName: 'onResizeStart' 194 }, 195 onPopupResize: { 196 namespace: 'BX.Main.Popup', 197 eventName: 'onResize' 198 }, 199 onPopupResizeEnd: { 200 namespace: 'BX.Main.Popup', 201 eventName: 'onResizeEnd' 202 } 203 }; 204 main_core_events.EventEmitter.registerAliases(aliases$1); 205 const disabledScrolls = new WeakMap(); 206 207 /** 208 * @memberof BX.Main 209 */ 210 var _focusTrap = /*#__PURE__*/new WeakMap(); 211 var _Popup_brand = /*#__PURE__*/new WeakSet(); 212 let Popup = /*#__PURE__*/function (_EventEmitter) { 213 function Popup(_options) { 214 var _this; 215 babelHelpers.classCallCheck(this, Popup); 216 _this = _callSuper$1(this, Popup); 217 _classPrivateMethodInitSpec$1(_this, _Popup_brand); 218 _classPrivateFieldInitSpec$1(_this, _focusTrap, null); 219 /** 220 * @private 221 */ 222 babelHelpers.defineProperty(_this, "handleAutoHide", event => { 223 if (_this.isDestroyed()) { 224 return; 225 } 226 if (_this.autoHideHandler !== null) { 227 if (_this.autoHideHandler(event)) { 228 _this._tryCloseByEvent(event); 229 } 230 } else if (event.target !== _this.getPopupContainer() && !_this.getPopupContainer().contains(event.target)) { 231 _this._tryCloseByEvent(event); 232 } 233 }); 234 /** 235 * @private 236 */ 237 babelHelpers.defineProperty(_this, "handleDocumentKeyUp", event => { 238 if (event.keyCode === 27 && !_this.isDestroyed()) { 239 checkEscPressed(_this.getZindex(), () => { 240 _this.close(); 241 }); 242 } 243 }); 244 _this.setEventNamespace('BX.Main.Popup'); 245 let [popupId, bindElement, params] = arguments; // compatible arguments 246 247 _this.compatibleMode = params && main_core.Type.isBoolean(params.compatibleMode) ? params.compatibleMode : true; 248 if (main_core.Type.isPlainObject(_options) && !bindElement && !params) { 249 params = _options; 250 popupId = _options.id; 251 bindElement = _options.bindElement; 252 _this.compatibleMode = false;
253 } 254 params = params || {}; 255 _this.params = params; 256 if (!main_core.Type.isStringFilled(popupId)) { 257 popupId = `popup-window-${main_core.Text.getRandom().toLowerCase()}`; 258 } 259 _this.emit('onInit', new main_core_events.BaseEvent({ 260 compatData: [popupId, bindElement, params] 261 })); 262 263 /** 264 * @private 265 */ 266 _this.uniquePopupId = popupId; 267 _this.params.zIndex = main_core.Type.isNumber(params.zIndex) ? parseInt(params.zIndex) : 0; 268 _this.params.zIndexAbsolute = main_core.Type.isNumber(params.zIndexAbsolute) ? parseInt(params.zIndexAbsolute) : 0; 269 _this.buttons = params.buttons && main_core.Type.isArray(params.buttons) ? params.buttons : []; 270 _this.offsetTop = Popup.getOption('offsetTop'); 271 _this.offsetLeft = Popup.getOption('offsetLeft'); 272 _this.firstShow = false; 273 _this.bordersWidth = 20; 274 _this.bindElementPos = null; 275 _this.closeIcon = null; 276 _this.resizeIcon = null; 277 _this.angle = null; 278 _this.angleArrowElement = null; 279 _this.overlay = null; 280 _this.titleBar = null; 281 _this.bindOptions = main_core.Type.isObject(params.bindOptions) ? params.bindOptions : {}; 282 _this.autoHide = params.autoHide === true; 283 _this.disableScroll = params.disableScroll === true || params.isScrollBlock === true; 284 _this.autoHideHandler = main_core.Type.isFunction(params.autoHideHandler) ? params.autoHideHandler : null; 285 _this.isAutoHideBinded = false; 286 _this.closeByEsc = params.closeByEsc === true; 287 _this.isCloseByEscBinded = false; 288 _this.toFrontOnShow = true; 289 _this.cacheable = true; 290 _this.destroyed = false; 291 _this.fixed = false; 292 _this.width = null; 293 _this.height = null; 294 _this.minWidth = null; 295 _this.minHeight = null; 296 _this.maxWidth = null; 297 _this.maxHeight = null; 298 _this.padding = null; 299 _this.contentPadding = null; 300 _this.background = null; 301 _this.contentBackground = null; 302 _this.borderRadius = null; 303 _this.contentBorderRadius = null; 304 _this.setTargetContainer(params.targetContainer); 305 _this.dragOptions = { 306 cursor: '', 307 callback: function () {}, 308 eventName: '' 309 }; 310 _this.dragged = false; 311 _this.dragPageX = 0; 312 _this.dragPageY = 0; 313 _this.animationShowClassName = null; 314 _this.animationCloseClassName = null; 315 _this.animationCloseEventType = null; 316 _this.handleDocumentMouseMove = _this.handleDocumentMouseMove.bind(_this); 317 _this.handleDocumentMouseUp = _this.handleDocumentMouseUp.bind(_this); 318 _this.handleResizeWindow = _this.handleResizeWindow.bind(_this); 319 _this.handleResize = _this.handleResize.bind(_this); 320 _this.handleMove = _this.handleMove.bind(_this); 321 _this.onTitleMouseDown = _this.onTitleMouseDown.bind(_this); 322 _this.handleFullScreen = _this.handleFullScreen.bind(_this); 323 _this.subscribeFromOptions(params.events); 324 let popupClassName = 'popup-window'; 325 if (params.titleBar) { 326 popupClassName += ' popup-window-with-titlebar'; 327 } 328 if (params.className && main_core.Type.isStringFilled(params.className)) { 329 popupClassName += ` ${params.className}`; 330 } 331 if (params.darkMode) { 332 popupClassName += ' popup-window-dark'; 333 } 334 _this.designSystemContext = params.darkMode ? '--ui-context-content-dark' : '--ui-context-content-light'; 335 popupClassName += ` ${_this.designSystemContext}`; 336 const titleBarId = `popup-window-titlebar-${popupId}`; 337 if (params.titleBar) { 338 _this.titleBar = main_core.Tag.render`<div class="popup-window-titlebar" id="${titleBarId}"></div>`; 339 } 340 if (params.closeIcon) { 341 let className = `popup-window-close-icon${params.titleBar ? ' popup-window-titlebar-close-icon' : ''}`; 342 if (Object.values(CloseIconSize).includes(params.closeIconSize) && params.closeIconSize !== CloseIconSize.SMALL) { 343 className += ` --${params.closeIconSize}`; 344 } 345 _this.closeIcon = main_core.Tag.render` 346 <button 347 tabindex="0" 348 type="button" 349 aria-label="Close" 350 class="${className}" 351 onclick="${_this.handleCloseIconClick.bind(_this)}" 352 > 353 <span class="ui-icon-set --cross-l --hoverable-default" style="--ui-icon-set__icon-size: 24px;"></span> 354 </button> 355 `; 356 if (main_core.Type.isPlainObject(params.closeIcon)) { 357 main_core.Dom.style(_this.closeIcon, params.closeIcon); 358 } 359 } 360 361 /** 362 * @private 363 */ 364 _this.contentContainer = main_core.Tag.render` 365 <div id="popup-window-content-${popupId}" role="presentation" class="popup-window-content"></div> 366 `; 367 368 /** 369 * @private 370 */ 371 _this.popupContainer = main_core.Tag.render` 372 <div 373 class="${popupClassName}" 374 id="${popupId}" 375 style="display: none; position: absolute; left: 0; top: 0;" 376 tabindex="-1" 377 role="${main_core.Type.isStringFilled(params.role) ? params.role : 'dialog'}" 378 >${[_this.titleBar, _this.contentContainer, _this.closeIcon]}</div> 379 `; 380 if (main_core.Type.isStringFilled(params.ariaLabel)) { 381 main_core.Dom.attr(_this.popupContainer, 'aria-label', params.ariaLabel); 382 } 383 if (main_core.Type.isStringFilled(params.ariaLabelledBy)) { 384 main_core.Dom.attr(_this.popupContainer, 'aria-labelledby', params.ariaLabelledBy); 385 } 386 _this.getTargetContainer().append(_this.popupContainer); 387 _this.zIndexComponent = main_core_zIndexManager.ZIndexManager.register(_this.popupContainer, params.zIndexOptions); 388 _this.buttonsContainer = null; 389 if (params.contentColor && main_core.Type.isStringFilled(params.contentColor)) { 390 _this.setContentColor(params.contentColor); 391 } 392 if (params.angle) { 393 _this.setAngle(params.angle); 394 } 395 if (params.overlay) { 396 _this.setOverlay(params.overlay); 397 } 398 _this.setOffset(params); 399 _this.setBindElement(bindElement); 400 _this.setTitleBar(params.titleBar); 401 _this.setDraggable(params.draggable); 402 _this.setContent(params.content); 403 _this.setButtons(params.buttons); 404 _this.setWidth(params.width); 405 _this.setHeight(params.height); 406 _this.setMinWidth(params.minWidth); 407 _this.setMinHeight(params.minHeight); 408 _this.setMaxWidth(params.maxWidth); 409 _this.setMaxHeight(params.maxHeight); 410 _this.setResizeMode(params.resizable); 411 _this.setPadding(params.padding); 412 _this.setContentPadding(params.contentPadding); 413 _this.setBorderRadius(params.borderRadius); 414 _this.setContentBorderRadius(params.contentBorderRadius);
415 _this.setBackground(params.background); 416 _this.setContentBackground(params.contentBackground); 417 _this.setAnimation(params.animation); 418 _this.setCacheable(params.cacheable); 419 _this.setToFrontOnShow(params.toFrontOnShow); 420 _this.setFixed(params.fixed); 421 _this.setDesignSystemContext(params.designSystemContext); 422 423 // Compatibility 424 if (params.contentNoPaddings) { 425 _this.setContentPadding(0); 426 } 427 if (params.noAllPaddings) { 428 _this.setPadding(0); 429 _this.setContentPadding(0); 430 } 431 if (params.bindOnResize !== false) { 432 main_core.Event.bind(window, 'resize', _this.handleResizeWindow); 433 } 434 _assertClassBrand$1(_Popup_brand, _this, _initFocusTrap).call(_this, params.focusTrap); 435 _this.emit('onAfterInit', new main_core_events.BaseEvent({ 436 compatData: [popupId, _this] 437 })); 438 return _this; 439 } 440 441 /** 442 * @private 443 */ 444 babelHelpers.inherits(Popup, _EventEmitter); 445 return babelHelpers.createClass(Popup, [{ 446 key: "subscribeFromOptions", 447 value: function subscribeFromOptions(events) { 448 _superPropGet(Popup, "subscribeFromOptions", this)([events, aliases$1]); 449 } 450 }, { 451 key: "getId", 452 value: function getId() { 453 return this.uniquePopupId; 454 } 455 }, { 456 key: "isCompatibleMode", 457 value: function isCompatibleMode() { 458 return this.compatibleMode; 459 } 460 }, { 461 key: "setContent", 462 value: function setContent(content) { 463 if (!this.contentContainer || !content) { 464 return; 465 } 466 if (main_core.Type.isElementNode(content)) { 467 main_core.Dom.clean(this.contentContainer); 468 const hasParent = main_core.Type.isDomNode(content.parentNode); 469 this.contentContainer.appendChild(content); 470 if (this.isCompatibleMode() || hasParent) { 471 content.style.display = 'block'; 472 } 473 } else if (main_core.Type.isString(content)) { 474 this.contentContainer.innerHTML = content; 475 } else { 476 this.contentContainer.innerHTML = ' '; 477 } 478 } 479 }, { 480 key: "setButtons", 481 value: function setButtons(buttons) { 482 this.buttons = buttons && main_core.Type.isArray(buttons) ? buttons : []; 483 if (this.buttonsContainer) { 484 main_core.Dom.remove(this.buttonsContainer); 485 } 486 const ButtonClass = main_core.Reflection.getClass('BX.UI.Button'); 487 if (this.buttons.length > 0 && this.contentContainer) { 488 const newButtons = []; 489 for (let i = 0; i < this.buttons.length; i++) { 490 const button = this.buttons[i]; 491 if (button instanceof Button) { 492 button.popupWindow = this; 493 newButtons.push(button.render()); 494 } else if (ButtonClass && button instanceof ButtonClass) { 495 button.setContext(this); 496 newButtons.push(button.render()); 497 } 498 } 499 this.buttonsContainer = main_core.Tag.render`<div class="popup-window-buttons">${newButtons}</div>`; 500 this.contentContainer.insertAdjacentElement('afterend', this.buttonsContainer); 501 } 502 } 503 }, { 504 key: "getButtons", 505 value: function getButtons() { 506 return this.buttons; 507 } 508 }, { 509 key: "getButton", 510 value: function getButton(id) { 511 for (let i = 0; i < this.buttons.length; i++) { 512 const button = this.buttons[i]; 513 if (button.getId() === id) { 514 return button; 515 } 516 } 517 return null; 518 } 519 }, { 520 key: "setBindElement", 521 value: function setBindElement(bindElement) { 522 if (bindElement === null) { 523 this.bindElement = null; 524 } else if (main_core.Type.isObject(bindElement)) { 525 if (main_core.Type.isDomNode(bindElement) || main_core.Type.isNumber(bindElement.top) && main_core.Type.isNumber(bindElement.left)) { 526 this.bindElement = bindElement; 527 } else if (main_core.Type.isNumber(bindElement.clientX) && main_core.Type.isNumber(bindElement.clientY)) { 528 this.bindElement = { 529 left: bindElement.pageX, 530 top: bindElement.pageY, 531 bottom: bindElement.pageY 532 }; 533 } 534 } 535 } 536 537 /** 538 * @private 539 */ 540 }, { 541 key: "getBindElementPos", 542 value: function getBindElementPos(bindElement) { 543 if (main_core.Type.isDomNode(bindElement)) { 544 if (this.isTargetDocumentBody()) { 545 return this.isFixed() ? bindElement.getBoundingClientRect() : main_core.Dom.getPosition(bindElement); 546 } 547 return this.getPositionRelativeToTarget(bindElement); 548 } 549 if (bindElement && main_core.Type.isObject(bindElement)) { 550 if (!main_core.Type.isNumber(bindElement.bottom)) { 551 bindElement.bottom = bindElement.top; 552 } 553 return bindElement; 554 } 555 const windowSize = this.getWindowSize(); 556 const windowScroll = this.getWindowScroll(); 557 const popupWidth = this.getPopupContainer().offsetWidth; 558 const popupHeight = this.getPopupContainer().offsetHeight; 559 this.bindOptions.forceTop = true; 560 return { 561 left: windowSize.innerWidth / 2 - popupWidth / 2 + windowScroll.scrollLeft,
562 top: windowSize.innerHeight / 2 - popupHeight / 2 + (this.isFixed() ? 0 : windowScroll.scrollTop), 563 bottom: windowSize.innerHeight / 2 - popupHeight / 2 + (this.isFixed() ? 0 : windowScroll.scrollTop), 564 // for optimisation purposes 565 windowSize, 566 windowScroll, 567 popupWidth, 568 popupHeight 569 }; 570 } 571 572 /** 573 * @internal 574 */ 575 }, { 576 key: "getPositionRelativeToTarget", 577 value: function getPositionRelativeToTarget(element) { 578 let offsetLeft = element.offsetLeft; 579 let offsetTop = element.offsetTop; 580 let offsetElement = element.offsetParent; 581 while (offsetElement && offsetElement !== this.getTargetContainer()) { 582 offsetLeft += offsetElement.offsetLeft; 583 offsetTop += offsetElement.offsetTop; 584 offsetElement = offsetElement.offsetParent; 585 } 586 const elementRect = element.getBoundingClientRect(); 587 return new DOMRect(offsetLeft, offsetTop, elementRect.width, elementRect.height); 588 } 589 590 // private 591 }, { 592 key: "getWindowSize", 593 value: function getWindowSize() { 594 if (this.isTargetDocumentBody()) { 595 return { 596 innerWidth: window.innerWidth, 597 innerHeight: window.innerHeight 598 }; 599 } 600 return { 601 innerWidth: this.getTargetContainer().offsetWidth, 602 innerHeight: this.getTargetContainer().offsetHeight 603 }; 604 } 605 606 // private 607 }, { 608 key: "getWindowScroll", 609 value: function getWindowScroll() { 610 if (this.isTargetDocumentBody()) { 611 return { 612 scrollLeft: window.pageXOffset, 613 scrollTop: window.pageYOffset 614 }; 615 } 616 return { 617 scrollLeft: this.getTargetContainer().scrollLeft, 618 scrollTop: this.getTargetContainer().scrollTop 619 }; 620 } 621 }, { 622 key: "setAngle", 623 value: function setAngle(params) { 624 if (params === false) { 625 if (this.angle !== null) { 626 main_core.Dom.remove(this.angle.element); 627 } 628 this.angle = null; 629 this.angleArrowElement = null; 630 return; 631 } 632 const className = 'popup-window-angly'; 633 if (this.angle === null) { 634 const position = this.bindOptions.position && this.bindOptions.position === 'top' ? 'bottom' : 'top'; 635 const angleMinLeft = Popup.getOption(position === 'top' ? 'angleMinTop' : 'angleMinBottom'); 636 let defaultOffset = main_core.Type.isNumber(params.offset) ? params.offset : 0; 637 const angleLeftOffset = Popup.getOption('angleLeftOffset', null); 638 if (defaultOffset > 0 && main_core.Type.isNumber(angleLeftOffset)) { 639 defaultOffset += angleLeftOffset - Popup.defaultOptions.angleLeftOffset; 640 } 641 this.angleArrowElement = main_core.Tag.render`<div class="popup-window-angly--arrow"></div>`; 642 if (this.background) { 643 this.angleArrowElement.style.background = this.background; 644 } 645 this.angle = { 646 element: main_core.Tag.render` 647 <div class="${className} ${className}-${position}"> 648 ${this.angleArrowElement} 649 </div> 650 `, 651 position, 652 offset: 0, 653 defaultOffset: Math.max(defaultOffset, angleMinLeft) 654 // Math.max(Type.isNumber(params.offset) ? params.offset : 0, angleMinLeft) 655 }; 656 this.getPopupContainer().appendChild(this.angle.element); 657 } 658 if (main_core.Type.isObject(params) && params.position && ['top', 'right', 'bottom', 'left', 'hide'].includes(params.position)) { 659 main_core.Dom.removeClass(this.angle.element, `${className}-${this.angle.position}`); 660 main_core.Dom.addClass(this.angle.element, `${className}-${params.position}`); 661 this.angle.position = params.position; 662 } 663 if (main_core.Type.isObject(params) && main_core.Type.isNumber(params.offset)) { 664 const offset = params.offset; 665 let minOffset, maxOffset; 666 if (this.angle.position === 'top') { 667 minOffset = Popup.getOption('angleMinTop'); 668 maxOffset = this.getPopupContainer().offsetWidth - Popup.getOption('angleMaxTop'); 669 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 670 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 671 this.angle.element.style.left = `${this.angle.offset}px`; 672 this.angle.element.style.marginLeft = 0; 673 this.angle.element.style.removeProperty('top'); 674 } else if (this.angle.position === 'bottom') { 675 minOffset = Popup.getOption('angleMinBottom'); 676 maxOffset = this.getPopupContainer().offsetWidth - Popup.getOption('angleMaxBottom'); 677 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 678 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 679 this.angle.element.style.marginLeft = `${this.angle.offset}px`; 680 this.angle.element.style.left = 0; 681 this.angle.element.style.removeProperty('top'); 682 } else if (this.angle.position === 'right') { 683 minOffset = Popup.getOption('angleMinRight'); 684 maxOffset = this.getPopupContainer().offsetHeight - Popup.getOption('angleMaxRight'); 685 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 686 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 687 this.angle.element.style.top = `${this.angle.offset}px`; 688 this.angle.element.style.removeProperty('left'); 689 this.angle.element.style.removeProperty('margin-left'); 690 } else if (this.angle.position === 'left') { 691 minOffset = Popup.getOption('angleMinLeft'); 692 maxOffset = this.getPopupContainer().offsetHeight - Popup.getOption('angleMaxLeft'); 693 maxOffset = maxOffset < minOffset ? Math.max(minOffset, offset) : maxOffset; 694 this.angle.offset = Math.min(Math.max(minOffset, offset), maxOffset); 695 this.angle.element.style.top = `${this.angle.offset}px`; 696 this.angle.element.style.removeProperty('left'); 697 this.angle.element.style.removeProperty('margin-left'); 698 } 699 } 700 } 701 }, {
702 key: "getWidth", 703 value: function getWidth() { 704 return this.width; 705 } 706 }, { 707 key: "setWidth", 708 value: function setWidth(width) { 709 this.setWidthProperty('width', width); 710 } 711 }, { 712 key: "getHeight", 713 value: function getHeight() { 714 return this.height; 715 } 716 }, { 717 key: "setHeight", 718 value: function setHeight(height) { 719 this.setHeightProperty('height', height); 720 } 721 }, { 722 key: "getMinWidth", 723 value: function getMinWidth() { 724 return this.minWidth; 725 } 726 }, { 727 key: "setMinWidth", 728 value: function setMinWidth(width) { 729 this.setWidthProperty('minWidth', width); 730 } 731 }, { 732 key: "getMinHeight", 733 value: function getMinHeight() { 734 return this.minHeight; 735 } 736 }, { 737 key: "setMinHeight", 738 value: function setMinHeight(height) { 739 this.setHeightProperty('minHeight', height); 740 } 741 }, { 742 key: "getMaxWidth", 743 value: function getMaxWidth() { 744 return this.maxWidth; 745 } 746 }, { 747 key: "setMaxWidth", 748 value: function setMaxWidth(width) { 749 this.setWidthProperty('maxWidth', width); 750 } 751 }, { 752 key: "getMaxHeight", 753 value: function getMaxHeight() { 754 return this.maxHeight; 755 } 756 }, { 757 key: "setMaxHeight", 758 value: function setMaxHeight(height) { 759 this.setHeightProperty('maxHeight', height); 760 } 761 762 /** 763 * @private 764 */ 765 }, { 766 key: "setWidthProperty", 767 value: function setWidthProperty(property, width) { 768 const props = ['width', 'minWidth', 'maxWidth']; 769 if (!props.includes(property)) { 770 return; 771 } 772 if (main_core.Type.isNumber(width) && width >= 0) { 773 this[property] = width; 774 this.getResizableContainer().style[property] = `${width}px`; 775 this.getContentContainer().style.overflowX = 'auto'; 776 this.getPopupContainer().classList.add('popup-window-fixed-width'); 777 } else if (width === null || width === false) { 778 this[property] = null; 779 this.getResizableContainer().style.removeProperty(main_core.Text.toKebabCase(property)); 780 const hasOtherProps = props.some(prop => { 781 return this.getResizableContainer().style.getPropertyValue(main_core.Text.toKebabCase(prop)) !== ''; 782 }); 783 if (!hasOtherProps) { 784 this.getContentContainer().style.removeProperty('overflow-x'); 785 this.getPopupContainer().classList.remove('popup-window-fixed-width'); 786 } 787 } 788 } 789 790 /** 791 * @private 792 */ 793 }, { 794 key: "setHeightProperty", 795 value: function setHeightProperty(property, height) { 796 const props = ['height', 'minHeight', 'maxHeight']; 797 if (!props.includes(property)) { 798 return; 799 } 800 if (main_core.Type.isNumber(height) && height >= 0) { 801 this[property] = height; 802 this.getResizableContainer().style[property] = `${height}px`; 803 this.getContentContainer().style.overflowY = 'auto'; 804 this.getPopupContainer().classList.add('popup-window-fixed-height'); 805 } else if (height === null || height === false) { 806 this[property] = null; 807 this.getResizableContainer().style.removeProperty(main_core.Text.toKebabCase(property)); 808 const hasOtherProps = props.some(prop => { 809 return this.getResizableContainer().style.getPropertyValue(main_core.Text.toKebabCase(prop)) !== ''; 810 }); 811 if (!hasOtherProps) { 812 this.getContentContainer().style.removeProperty('overflow-y'); 813 this.getPopupContainer().classList.remove('popup-window-fixed-height'); 814 } 815 } 816 } 817 }, { 818 key: "setPadding", 819 value: function setPadding(padding) { 820 if (main_core.Type.isNumber(padding) && padding >= 0) { 821 this.padding = padding; 822 this.getPopupContainer().style.padding = `${padding}px`; 823 } else if (padding === null) { 824 this.padding = null; 825 this.getPopupContainer().style.removeProperty('padding'); 826 } 827 } 828 }, { 829 key: "getPadding", 830 value: function getPadding() { 831 return this.padding; 832 } 833 }, { 834 key: "setContentPadding", 835 value: function setContentPadding(padding) { 836 if (main_core.Type.isNumber(padding) && padding >= 0) { 837 this.contentPadding = padding; 838 this.getContentContainer().style.padding = `${padding}px`; 839 } else if (padding === null) { 840 this.contentPadding = null; 841 this.getContentContainer().style.removeProperty('padding'); 842 } 843 } 844 }, { 845 key: "getContentPadding", 846 value: function getContentPadding() { 847 return this.contentPadding; 848 } 849 }, { 850 key: "setBorderRadius", 851 value: function setBorderRadius(radius) { 852 if (main_core.Type.isStringFilled(radius)) {
853 this.borderRadius = radius; 854 this.getPopupContainer().style.setProperty('--popup-window-border-radius', radius); 855 } else if (radius === null) { 856 this.borderRadius = null; 857 this.getPopupContainer().style.removeProperty('--popup-window-border-radius'); 858 } 859 } 860 }, { 861 key: "setContentBorderRadius", 862 value: function setContentBorderRadius(radius) { 863 if (main_core.Type.isStringFilled(radius)) { 864 this.contentBorderRadius = radius; 865 this.getContentContainer().style.setProperty('--popup-window-content-border-radius', radius); 866 } else if (radius === null) { 867 this.contentBorderRadius = null; 868 this.getContentContainer().style.removeProperty('--popup-window-content-border-radius'); 869 } 870 } 871 }, { 872 key: "setContentColor", 873 value: function setContentColor(color) { 874 if (main_core.Type.isString(color) && this.contentContainer) { 875 this.contentContainer.style.backgroundColor = color; 876 } else if (color === null) { 877 this.contentContainer.style.style.removeProperty('background-color'); 878 } 879 } 880 }, { 881 key: "setBackground", 882 value: function setBackground(background) { 883 if (main_core.Type.isStringFilled(background)) { 884 this.background = background; 885 this.getPopupContainer().style.background = background; 886 if (this.angleArrowElement) { 887 this.angleArrowElement.style.background = background; 888 } 889 } else if (background === null) { 890 this.background = null; 891 this.getPopupContainer().style.removeProperty('background'); 892 if (this.angleArrowElement) { 893 this.angleArrowElement.style.removeProperty('background'); 894 } 895 } 896 } 897 }, { 898 key: "getBackground", 899 value: function getBackground() { 900 return this.background; 901 } 902 }, { 903 key: "setContentBackground", 904 value: function setContentBackground(background) { 905 if (main_core.Type.isStringFilled(background)) { 906 this.contentBackground = background; 907 this.getContentContainer().style.background = background; 908 } else if (background === null) { 909 this.contentBackground = null; 910 this.getContentContainer().style.removeProperty('background'); 911 } 912 } 913 }, { 914 key: "getContentBackground", 915 value: function getContentBackground() { 916 return this.contentBackground; 917 } 918 }, { 919 key: "isDestroyed", 920 value: function isDestroyed() { 921 return this.destroyed; 922 } 923 }, { 924 key: "setCacheable", 925 value: function setCacheable(cacheable) { 926 this.cacheable = cacheable !== false; 927 } 928 }, { 929 key: "isCacheable", 930 value: function isCacheable() { 931 return this.cacheable; 932 } 933 }, { 934 key: "getFocusTrap", 935 value: function getFocusTrap() { 936 return _classPrivateFieldGet$1(_focusTrap, this); 937 } 938 }, { 939 key: "setToFrontOnShow", 940 value: function setToFrontOnShow(flag) { 941 this.toFrontOnShow = flag !== false; 942 } 943 }, { 944 key: "shouldFrontOnShow", 945 value: function shouldFrontOnShow() { 946 return this.toFrontOnShow; 947 } 948 }, { 949 key: "setFixed", 950 value: function setFixed(flag) { 951 if (main_core.Type.isBoolean(flag)) { 952 this.fixed = flag; 953 if (flag) { 954 main_core.Dom.addClass(this.getPopupContainer(), '--fixed'); 955 } else { 956 main_core.Dom.removeClass(this.getPopupContainer(), '--fixed'); 957 } 958 } 959 } 960 }, { 961 key: "isFixed", 962 value: function isFixed() { 963 return this.fixed; 964 } 965 }, { 966 key: "setResizeMode", 967 value: function setResizeMode(mode) { 968 if (mode === true || main_core.Type.isPlainObject(mode)) { 969 if (!this.resizeIcon) { 970 this.resizeIcon = main_core.Tag.render` 971 <div class="popup-window-resize" onmousedown="${this.handleResizeMouseDown.bind(this)}"></div> 972 `; 973 this.getPopupContainer().appendChild(this.resizeIcon); 974 } 975 976 // Compatibility 977 this.setMinWidth(mode.minWidth); 978 this.setMinHeight(mode.minHeight); 979 } else if (mode === false && this.resizeIcon) { 980 main_core.Dom.remove(this.resizeIcon); 981 this.resizeIcon = null; 982 } 983 } 984 }, { 985 key: "getDesignSystemContext", 986 value: function getDesignSystemContext() { 987 return this.designSystemContext; 988 } 989 }, { 990 key: "setDesignSystemContext", 991 value: function setDesignSystemContext(context) { 992 if (main_core.Type.isString(context)) { 993 if (this.popupContainer !== null) { 994 main_core.Dom.removeClass(this.popupContainer, this.designSystemContext); 995 main_core.Dom.addClass(this.popupContainer, context); 996 } 997 this.designSystemContext = context; 998 } 999 } 1000 }, { 1001 key: "setTargetContainer", 1002 value: function setTargetContainer(targetContainer) { 1003 const newTargetContainer = main_core.Type.isElementNode(targetContainer) ? targetContainer : document.body; 1004 if (newTargetContainer === this.targetContainer) { 1005 return; 1006 } 1007 this.targetContainer = newTargetContainer; 1008 if (this.getPopupContainer()) { 1009 main_core_zIndexManager.ZIndexManager.unregister(this.getPopupContainer()); 1010 this.getTargetContainer().append(this.getPopupContainer()); 1011 main_core_zIndexManager.ZIndexManager.register(this.getPopupContainer()); 1012 } 1013 if (this.overlay) { 1014 main_core.Dom.append(this.overlay.element, this.getTargetContainer()); 1015 } 1016 } 1017 }, { 1018 key: "getTargetContainer", 1019 value: function getTargetContainer() { 1020 return this.targetContainer; 1021 } 1022 }, { 1023 key: "isTargetDocumentBody", 1024 value: function isTargetDocumentBody() { 1025 return this.getTargetContainer() === document.body; 1026 } 1027 }, { 1028 key: "getPopupContainer", 1029 value: function getPopupContainer() { 1030 return this.popupContainer; 1031 } 1032 }, { 1033 key: "getContentContainer", 1034 value: function getContentContainer() { 1035 return this.contentContainer; 1036 } 1037 }, { 1038 key: "getResizableContainer", 1039 value: function getResizableContainer() { 1040 return this.getPopupContainer(); 1041 } 1042 }, { 1043 key: "getTitleContainer", 1044 value: function getTitleContainer() { 1045 return this.titleBar; 1046 } 1047 1048 /** 1049 * @private 1050 */ 1051 }, { 1052 key: "onTitleMouseDown", 1053 value: function onTitleMouseDown(event) { 1054 _assertClassBrand$1(_Popup_brand, this, _startDrag).call(this, event, { 1055 cursor: 'move', 1056 callback: this.handleMove, 1057 eventName: 'Drag' 1058 }); 1059 } 1060 1061 /** 1062 * @private 1063 */ 1064 }, { 1065 key: "handleResizeMouseDown", 1066 value: function handleResizeMouseDown(event) { 1067 _assertClassBrand$1(_Popup_brand, this, _startDrag).call(this, event, { 1068 cursor: 'nwse-resize', 1069 eventName: 'Resize', 1070 callback: this.handleResize 1071 }); 1072 if (this.isTargetDocumentBody()) { 1073 this.resizeContentPos = main_core.Dom.getPosition(this.getResizableContainer()); 1074 this.resizeContentOffset = this.resizeContentPos.left - main_core.Dom.getPosition(this.getPopupContainer()).left; 1075 } else { 1076 this.resizeContentPos = this.getPositionRelativeToTarget(this.getResizableContainer()); 1077 this.resizeContentOffset = this.resizeContentPos.left - this.getPositionRelativeToTarget(this.getPopupContainer()).left; 1078 } 1079 this.resizeContentPos.offsetX = 0; 1080 this.resizeContentPos.offsetY = 0; 1081 } 1082 1083 /** 1084 * @private 1085 */ 1086 }, { 1087 key: "handleResize", 1088 value: function handleResize(offsetX, offsetY, pageX, pageY) { 1089 this.resizeContentPos.offsetX += offsetX; 1090 this.resizeContentPos.offsetY += offsetY; 1091 let width = this.resizeContentPos.width + this.resizeContentPos.offsetX; 1092 let height = this.resizeContentPos.height + this.resizeContentPos.offsetY; 1093 const scrollWidth = this.isTargetDocumentBody() ? document.documentElement.scrollWidth : this.getTargetContainer().scrollWidth; 1094 if (this.resizeContentPos.left + width + this.resizeContentOffset >= scrollWidth) { 1095 width = scrollWidth - this.resizeContentPos.left - this.resizeContentOffset; 1096 } 1097 width = Math.max(width, this.getMinWidth()); 1098 height = Math.max(height, this.getMinHeight()); 1099 if (this.getMaxWidth() !== null) { 1100 width = Math.min(width, this.getMaxWidth()); 1101 } 1102 if (this.getMaxHeight() !== null) { 1103 height = Math.min(height, this.getMaxHeight()); 1104 } 1105 this.setWidth(width); 1106 this.setHeight(height); 1107 } 1108 }, { 1109 key: "isTopAngle", 1110 value: function isTopAngle() { 1111 return this.angle !== null && this.angle.position === 'top'; 1112 } 1113 }, { 1114 key: "isBottomAngle", 1115 value: function isBottomAngle() { 1116 return this.angle !== null && this.angle.position === 'bottom'; 1117 } 1118 }, { 1119 key: "isTopOrBottomAngle", 1120 value: function isTopOrBottomAngle() { 1121 return this.angle !== null && (this.angle.position === 'top' || this.angle.position === 'bottom'); 1122 } 1123 1124 /** 1125 * @private 1126 */ 1127 }, { 1128 key: "getAngleHeight", 1129 value: function getAngleHeight() { 1130 return this.isTopOrBottomAngle() ? Popup.getOption('angleTopOffset') : 0; 1131 } 1132 }, { 1133 key: "setOffset", 1134 value: function setOffset(params) { 1135 if (!main_core.Type.isPlainObject(params)) { 1136 return; 1137 } 1138 if (main_core.Type.isNumber(params.offsetLeft)) { 1139 this.offsetLeft = params.offsetLeft + Popup.getOption('offsetLeft'); 1140 } 1141 if (main_core.Type.isNumber(params.offsetTop)) { 1142 this.offsetTop = params.offsetTop + Popup.getOption('offsetTop'); 1143 } 1144 } 1145 }, { 1146 key: "setTitleBar", 1147 value: function setTitleBar(params) { 1148 if (!this.titleBar) { 1149 return; 1150 } 1151 if (main_core.Type.isObject(params) && main_core.Type.isDomNode(params.content)) { 1152 this.titleBar.innerHTML = ''; 1153 this.titleBar.appendChild(params.content); 1154 } else if (main_core.Type.isString(params)) { 1155 this.titleBar.innerHTML = ''; 1156 this.titleBar.appendChild(main_core.Dom.create('span', { 1157 props: { 1158 id: `popup-window-titlebar-text-${this.getId()}`, 1159 className: 'popup-window-titlebar-text' 1160 }, 1161 text: params 1162 })); 1163 if (!main_core.Type.isStringFilled(main_core.Dom.attr(this.getPopupContainer(), 'aria-label'))) { 1164 main_core.Dom.attr(this.getPopupContainer(), 'aria-label', params); 1165 } 1166 } 1167 } 1168 }, { 1169 key: "setDraggable", 1170 value: function setDraggable(draggable) { 1171 this.params.draggable = draggable; 1172 const element = draggable?.element ?? this.titleBar; 1173 if (!draggable || !element) { 1174 return; 1175 }
1176 main_core.Dom.style(element, 'cursor', 'move'); 1177 main_core.Event.bind(element, 'mousedown', this.onTitleMouseDown); 1178 } 1179 }, { 1180 key: "setClosingByEsc", 1181 value: function setClosingByEsc(enable) { 1182 enable = main_core.Type.isBoolean(enable) ? enable : true; 1183 if (enable) { 1184 this.closeByEsc = true; 1185 this.bindClosingByEsc(); 1186 } else { 1187 this.closeByEsc = false; 1188 this.unbindClosingByEsc(); 1189 } 1190 } 1191 1192 /** 1193 * @private 1194 */ 1195 }, { 1196 key: "bindClosingByEsc", 1197 value: function bindClosingByEsc() { 1198 if (this.closeByEsc && !this.isCloseByEscBinded) { 1199 main_core.Event.bind(this.targetContainer.ownerDocument, 'keyup', this.handleDocumentKeyUp, true); 1200 this.isCloseByEscBinded = true; 1201 } 1202 } 1203 1204 /** 1205 * @private 1206 */ 1207 }, { 1208 key: "unbindClosingByEsc", 1209 value: function unbindClosingByEsc() { 1210 if (this.isCloseByEscBinded) { 1211 main_core.Event.unbind(this.targetContainer.ownerDocument, 'keyup', this.handleDocumentKeyUp, true); 1212 this.isCloseByEscBinded = false; 1213 } 1214 } 1215 }, { 1216 key: "setAutoHide", 1217 value: function setAutoHide(enable) { 1218 enable = main_core.Type.isBoolean(enable) ? enable : true; 1219 if (enable) { 1220 this.autoHide = true; 1221 this.bindAutoHide(); 1222 } else { 1223 this.autoHide = false;
1224 this.unbindAutoHide(); 1225 } 1226 } 1227 1228 /** 1229 * @private 1230 */ 1231 }, { 1232 key: "bindAutoHide", 1233 value: function bindAutoHide() { 1234 if (this.autoHide && !this.isAutoHideBinded && this.isShown()) { 1235 this.isAutoHideBinded = true; 1236 if (this.isCompatibleMode()) { 1237 main_core.Event.bind(this.getPopupContainer(), 'click', this.handleContainerClick); 1238 } 1239 if (!this.hasOverlay()) { 1240 main_core.Event.bind(this.targetContainer.ownerDocument, 'click', this.handleAutoHide, !this.isCompatibleMode()); 1241 } 1242 } 1243 } 1244 1245 /** 1246 * @private 1247 */ 1248 }, { 1249 key: "unbindAutoHide", 1250 value: function unbindAutoHide() { 1251 if (this.isAutoHideBinded) { 1252 this.isAutoHideBinded = false; 1253 if (this.isCompatibleMode()) { 1254 main_core.Event.unbind(this.getPopupContainer(), 'click', this.handleContainerClick); 1255 } 1256 if (!this.hasOverlay()) { 1257 main_core.Event.unbind(this.targetContainer.ownerDocument, 'click', this.handleAutoHide, !this.isCompatibleMode()); 1258 } 1259 } 1260 } 1261 }, { 1262 key: "_tryCloseByEvent", 1263 value: 1264 /** 1265 * @private 1266 */ 1267 function _tryCloseByEvent(event) { 1268 if (this.isCompatibleMode()) { 1269 this.tryCloseByEvent(event); 1270 } else { 1271 setTimeout(() => { 1272 this.tryCloseByEvent(event); 1273 }, 0); 1274 } 1275 } 1276 1277 /** 1278 * @private 1279 */ 1280 }, { 1281 key: "tryCloseByEvent", 1282 value: function tryCloseByEvent(event) { 1283 if (event.button === 0) { 1284 this.close(); 1285 } 1286 } 1287 1288 /** 1289 * @private 1290 */ 1291 }, { 1292 key: "handleOverlayClick", 1293 value: function handleOverlayClick(event) { 1294 if (this.autoHide) { 1295 this.tryCloseByEvent(event); 1296 event.stopPropagation(); 1297 } 1298 } 1299 }, { 1300 key: "setOverlay", 1301 value: function setOverlay(params) { 1302 if (this.overlay === null) { 1303 this.unbindAutoHide(); 1304 this.overlay = { 1305 element: main_core.Tag.render` 1306 <div 1307 class="popup-window-overlay" 1308 id="popup-window-overlay-${this.getId()}" 1309 onclick="${this.handleOverlayClick.bind(this)}" 1310 aria-hidden="true" 1311 ></div> 1312 ` 1313 }; 1314 this.resizeOverlay(); 1315 main_core.Dom.append(this.overlay.element, this.getTargetContainer()); 1316 this.getZIndexComponent().setOverlay(this.overlay.element); 1317 } 1318 if (main_core.Type.isNumber(params?.opacity) && params.opacity >= 0 && params.opacity <= 100) { 1319 main_core.Dom.style(this.overlay.element, 'opacity', parseFloat(params.opacity / 100).toPrecision(3)); 1320 } 1321 if (params?.backgroundColor) { 1322 main_core.Dom.style(this.overlay.element, 'background-color', params.backgroundColor); 1323 } 1324 if (params?.blur) { 1325 main_core.Dom.style(this.overlay.element, 'backdrop-filter', params.blur); 1326 } 1327 } 1328 }, { 1329 key: "isModal", 1330 value: function isModal() { 1331 return this.hasOverlay(); 1332 } 1333 }, { 1334 key: "hasOverlay", 1335 value: function hasOverlay() { 1336 return this.overlay !== null && this.overlay.element !== null; 1337 } 1338 }, { 1339 key: "removeOverlay", 1340 value: function removeOverlay() { 1341 if (this.overlay !== null && this.overlay.element !== null) { 1342 main_core.Dom.remove(this.overlay.element); 1343 this.getZIndexComponent().setOverlay(null); 1344 } 1345 if (this.overlayTimeout) { 1346 clearInterval(this.overlayTimeout); 1347 this.overlayTimeout = null; 1348 } 1349 this.overlay = null; 1350 } 1351 }, { 1352 key: "hideOverlay", 1353 value: function hideOverlay() { 1354 if (this.overlay !== null && this.overlay.element !== null) { 1355 if (this.overlayTimeout) { 1356 clearInterval(this.overlayTimeout); 1357 this.overlayTimeout = null; 1358 } 1359 this.overlay.element.style.display = 'none'; 1360 } 1361 } 1362 }, { 1363 key: "showOverlay", 1364 value: function showOverlay() { 1365 if (this.overlay !== null && this.overlay.element !== null) { 1366 this.overlay.element.style.display = 'block'; 1367 let popupHeight = this.getPopupContainer().offsetHeight; 1368 this.overlayTimeout = setInterval(() => { 1369 if (popupHeight !== this.getPopupContainer().offsetHeight) { 1370 this.resizeOverlay(); 1371 popupHeight = this.getPopupContainer().offsetHeight; 1372 } 1373 }, 1000); 1374 } 1375 } 1376 }, { 1377 key: "resizeOverlay", 1378 value: function resizeOverlay() { 1379 if (this.overlay !== null && this.overlay.element !== null) { 1380 let scrollWidth = 0; 1381 let scrollHeight = 0; 1382 if (this.isTargetDocumentBody()) { 1383 scrollWidth = document.documentElement.scrollWidth; 1384 scrollHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight); 1385 } else { 1386 scrollWidth = this.getTargetContainer().scrollWidth; 1387 scrollHeight = this.getTargetContainer().scrollHeight; 1388 } 1389 this.overlay.element.style.width = `${scrollWidth}px`; 1390 this.overlay.element.style.height = `${scrollHeight}px`; 1391 } 1392 } 1393 }, { 1394 key: "getZindex", 1395 value: function getZindex() { 1396 return this.getZIndexComponent().getZIndex(); 1397 } 1398 }, { 1399 key: "getZIndexComponent", 1400 value: function getZIndexComponent() { 1401 return this.zIndexComponent; 1402 } 1403 }, { 1404 key: "setDisableScroll", 1405 value: function setDisableScroll(flag) { 1406 const disable = main_core.Type.isBoolean(flag) ? flag : true; 1407 if (disable) { 1408 this.disableScroll = true; 1409 _assertClassBrand$1(_Popup_brand, this, _disableTargetScroll).call(this); 1410 } else { 1411 this.disableScroll = false;
1412 _assertClassBrand$1(_Popup_brand, this, _enableTargetScroll).call(this); 1413 } 1414 } 1415 }, { 1416 key: "show", 1417 value: function show() { 1418 if (this.isShown() || this.isDestroyed()) { 1419 return; 1420 } 1421 this.emit('onBeforeShow'); 1422 this.showOverlay(); 1423 this.getPopupContainer().style.display = 'block'; 1424 main_core.Dom.addClass(this.getPopupContainer(), '--open'); 1425 _classPrivateFieldGet$1(_focusTrap, this)?.captureActiveElement(); 1426 if (this.shouldFrontOnShow()) { 1427 this.bringToFront(); 1428 } 1429 if (!this.firstShow) { 1430 this.emit('onFirstShow', new main_core_events.BaseEvent({ 1431 compatData: [this] 1432 })); 1433 this.firstShow = true; 1434 } 1435 this.emit('onShow', new main_core_events.BaseEvent({ 1436 compatData: [this] 1437 })); 1438 if (this.disableScroll) { 1439 _assertClassBrand$1(_Popup_brand, this, _disableTargetScroll).call(this); 1440 } 1441 this.adjustPosition(); 1442 this.animateOpening(() => { 1443 if (this.isDestroyed()) { 1444 return; 1445 } 1446 main_core.Dom.removeClass(this.getPopupContainer(), this.animationShowClassName); 1447 this.emit('onAfterShow', new main_core_events.BaseEvent({ 1448 compatData: [this] 1449 })); 1450 _classPrivateFieldGet$1(_focusTrap, this)?.activate(); 1451 }); 1452 this.bindClosingByEsc(); 1453 if (this.isCompatibleMode()) { 1454 setTimeout(() => { 1455 this.bindAutoHide(); 1456 }, 100); 1457 } else { 1458 this.bindAutoHide(); 1459 } 1460 } 1461 }, { 1462 key: "close", 1463 value: function close() { 1464 if (this.isDestroyed() || !this.isShown()) { 1465 return; 1466 } 1467 this.emit('onClose', new main_core_events.BaseEvent({ 1468 compatData: [this] 1469 })); 1470 if (this.isDestroyed()) { 1471 return; 1472 } 1473 if (this.disableScroll) { 1474 _assertClassBrand$1(_Popup_brand, this, _enableTargetScroll).call(this); 1475 } 1476 _classPrivateFieldGet$1(_focusTrap, this)?.deactivate(); 1477 this.animateClosing(() => { 1478 if (this.isDestroyed()) { 1479 return; 1480 } 1481 this.hideOverlay(); 1482 this.getPopupContainer().style.display = 'none'; 1483 main_core.Dom.removeClass(this.getPopupContainer(), '--open'); 1484 main_core.Dom.removeClass(this.getPopupContainer(), this.animationCloseClassName); 1485 this.unbindClosingByEsc(); 1486 if (this.isCompatibleMode()) { 1487 setTimeout(() => { 1488 this.unbindAutoHide(); 1489 }, 0); 1490 } else { 1491 this.unbindAutoHide(); 1492 } 1493 this.emit('onAfterClose', new main_core_events.BaseEvent({ 1494 compatData: [this] 1495 })); 1496 if (!this.isCacheable()) { 1497 this.destroy(); 1498 } 1499 }); 1500 } 1501 }, { 1502 key: "bringToFront", 1503 value: function bringToFront() { 1504 if (this.isShown()) { 1505 main_core_zIndexManager.ZIndexManager.bringToFront(this.getPopupContainer()); 1506 } 1507 } 1508 }, { 1509 key: "toggle", 1510 value: function toggle() { 1511 if (this.isShown()) { 1512 this.close(); 1513 } else { 1514 this.show(); 1515 } 1516 } 1517 1518 /** 1519 * 1520 * @private 1521 */ 1522 }, { 1523 key: "animateOpening", 1524 value: function animateOpening(callback) { 1525 main_core.Dom.removeClass(this.getPopupContainer(), this.animationCloseClassName); 1526 if (this.animationShowClassName === null) { 1527 callback(); 1528 } else { 1529 main_core.Dom.addClass(this.getPopupContainer(), this.animationShowClassName); 1530 if (this.animationCloseEventType === null) { 1531 callback(); 1532 } else { 1533 const eventName = `${this.animationCloseEventType}end`; 1534 const className = this.animationShowClassName; 1535 this.getPopupContainer().addEventListener(eventName, function handleTransitionEnd(event) { 1536 if (!main_core.Dom.hasClass(event.target, className)) { 1537 return; 1538 } 1539 this.removeEventListener(eventName, handleTransitionEnd); 1540 callback(); 1541 }); 1542 } 1543 } 1544 } 1545 1546 /** 1547 * @private 1548 */ 1549 }, { 1550 key: "animateClosing", 1551 value: function animateClosing(callback) { 1552 main_core.Dom.removeClass(this.getPopupContainer(), this.animationShowClassName); 1553 if (this.animationCloseClassName === null) { 1554 callback(); 1555 } else { 1556 main_core.Dom.addClass(this.getPopupContainer(), this.animationCloseClassName); 1557 if (this.animationCloseEventType === null) { 1558 callback(); 1559 } else { 1560 const eventName = `${this.animationCloseEventType}end`; 1561 const className = this.animationCloseClassName; 1562 this.getPopupContainer().addEventListener(eventName, function handleTransitionEnd(event) { 1563 if (!main_core.Dom.hasClass(event.target, className)) { 1564 return; 1565 } 1566 this.removeEventListener(eventName, handleTransitionEnd); 1567 callback(); 1568 }); 1569 } 1570 } 1571 } 1572 }, { 1573 key: "setAnimation", 1574 value: function setAnimation(options) { 1575 if (main_core.Type.isPlainObject(options)) { 1576 this.animationShowClassName = main_core.Type.isStringFilled(options.showClassName) ? options.showClassName : null; 1577 this.animationCloseClassName = main_core.Type.isStringFilled(options.closeClassName) ? options.closeClassName : null; 1578 this.animationCloseEventType = options.closeAnimationType === 'animation' || options.closeAnimationType === 'transition' ? options.closeAnimationType : null; 1579 } else if (main_core.Type.isStringFilled(options)) { 1580 const animationName = options; 1581 if (animationName === 'fading') { 1582 this.animationShowClassName = 'popup-window-show-animation-opacity'; 1583 this.animationCloseClassName = 'popup-window-close-animation-opacity'; 1584 this.animationCloseEventType = 'animation'; 1585 } else if (animationName === 'fading-slide') { 1586 this.animationShowClassName = 'popup-window-show-animation-opacity-transform'; 1587 this.animationCloseClassName = 'popup-window-close-animation-opacity'; 1588 this.animationCloseEventType = 'animation'; 1589 } else if (animationName === 'scale') { 1590 this.animationShowClassName = 'popup-window-show-animation-scale'; 1591 this.animationCloseClassName = 'popup-window-close-animation-opacity'; 1592 this.animationCloseEventType = 'animation'; 1593 } 1594 } else if (options === false || options === null) { 1595 this.animationShowClassName = null; 1596 this.animationCloseClassName = null; 1597 this.animationCloseEventType = null; 1598 } 1599 } 1600 }, { 1601 key: "isShown", 1602 value: function isShown() { 1603 return !this.isDestroyed() && this.getPopupContainer()?.style.display === 'block'; 1604 } 1605 }, {
1606 key: "destroy", 1607 value: function destroy() { 1608 if (this.destroyed) { 1609 return; 1610 } 1611 if (this.disableScroll) { 1612 _assertClassBrand$1(_Popup_brand, this, _enableTargetScroll).call(this); 1613 } 1614 this.destroyed = true; 1615 this.emit('onDestroy', new main_core_events.BaseEvent({ 1616 compatData: [this] 1617 })); 1618 this.unbindClosingByEsc(); 1619 if (this.isCompatibleMode()) { 1620 setTimeout(() => { 1621 this.unbindAutoHide(); 1622 }, 0); 1623 } else { 1624 this.unbindAutoHide(); 1625 } 1626 main_core.Event.unbindAll(this); 1627 main_core.Event.unbind(document, 'mousemove', this.handleDocumentMouseMove); 1628 main_core.Event.unbind(document, 'mouseup', this.handleDocumentMouseUp); 1629 main_core.Event.unbind(window, 'resize', this.handleResizeWindow); 1630 this.removeOverlay(); 1631 main_core_zIndexManager.ZIndexManager.unregister(this.popupContainer); 1632 this.zIndexComponent = null; 1633 _classPrivateFieldGet$1(_focusTrap, this)?.destroy(); 1634 _classPrivateFieldSet$1(_focusTrap, this, null); 1635 main_core.Dom.remove(this.popupContainer); 1636 this.popupContainer = null; 1637 this.contentContainer = null; 1638 this.closeIcon = null; 1639 this.titleBar = null; 1640 this.buttonsContainer = null; 1641 this.angle = null; 1642 this.angleArrowElement = null; 1643 this.resizeIcon = null; 1644 } 1645 }, { 1646 key: "adjustPosition", 1647 value: function adjustPosition(bindOptions) { 1648 if (bindOptions && main_core.Type.isObject(bindOptions)) { 1649 this.bindOptions = bindOptions; 1650 } 1651 const bindElementPos = this.getBindElementPos(this.bindElement); 1652 if (!this.bindOptions.forceBindPosition && this.bindElementPos !== null && bindElementPos.top === this.bindElementPos.top && bindElementPos.left === this.bindElementPos.left) { 1653 return; 1654 } 1655 const bindElementVanished = bindElementPos.top === 0 && bindElementPos.left === 0 && bindElementPos.width === 0 && bindElementPos.height === 0; 1656 this.bindElementPos = bindElementVanished && this.bindElementPos !== null ? this.bindElementPos : bindElementPos; 1657 const windowSize = bindElementPos.windowSize ?? this.getWindowSize(); 1658 const windowScroll = bindElementPos.windowScroll ?? this.getWindowScroll(); 1659 const popupWidth = bindElementPos.popupWidth ?? this.popupContainer.offsetWidth; 1660 const popupHeight = bindElementPos.popupHeight ?? this.popupContainer.offsetHeight; 1661 const angleTopOffset = Popup.getOption('angleTopOffset'); 1662 let left = this.bindElementPos.left + this.offsetLeft - (this.isTopOrBottomAngle() ? Popup.getOption('angleLeftOffset') : 0); 1663 if (!this.bindOptions.forceLeft && left + popupWidth + this.bordersWidth >= windowSize.innerWidth + windowScroll.scrollLeft && windowSize.innerWidth + windowScroll.scrollLeft - popupWidth - this.bordersWidth > 0) { 1664 const bindLeft = left; 1665 left = windowSize.innerWidth + windowScroll.scrollLeft - popupWidth - this.bordersWidth; 1666 if (this.isTopOrBottomAngle()) { 1667 this.setAngle({ 1668 offset: bindLeft - left + this.angle.defaultOffset 1669 }); 1670 } 1671 } else if (this.isTopOrBottomAngle()) { 1672 this.setAngle({ 1673 offset: this.angle.defaultOffset + (left < 0 ? left : 0) 1674 }); 1675 } 1676 if (left < 0) { 1677 left = 0; 1678 } 1679 let top = 0; 1680 if (this.bindOptions.position && this.bindOptions.position === 'top') { 1681 top = this.bindElementPos.top - popupHeight - this.offsetTop - (this.isBottomAngle() ? angleTopOffset : 0); 1682 if (top < 0 || !this.bindOptions.forceTop && top < windowScroll.scrollTop) { 1683 top = this.bindElementPos.bottom + this.offsetTop; 1684 if (this.angle !== null) { 1685 top += angleTopOffset; 1686 this.setAngle({ 1687 position: 'top' 1688 }); 1689 } 1690 } else if (this.isTopAngle()) { 1691 top = top - angleTopOffset + Popup.getOption('positionTopXOffset'); 1692 this.setAngle({ 1693 position: 'bottom' 1694 }); 1695 } else { 1696 top += Popup.getOption('positionTopXOffset'); 1697 } 1698 } else { 1699 top = this.bindElementPos.bottom + this.offsetTop + this.getAngleHeight(); 1700 if (!this.bindOptions.forceTop && top + popupHeight >
1700 windowSize.innerHeight + windowScroll.scrollTop 1701 // Can we place the PopupWindow above the bindElement? 1702 && this.bindElementPos.top - popupHeight - this.getAngleHeight() >= 0) { 1703 // The PopupWindow doesn't place below the bindElement. We should place it above. 1704 top = this.bindElementPos.top - popupHeight; 1705 if (this.isTopOrBottomAngle()) { 1706 top -= angleTopOffset; 1707 this.setAngle({ 1708 position: 'bottom' 1709 }); 1710 } 1711 top += Popup.getOption('positionTopXOffset'); 1712 } else if (this.isBottomAngle()) { 1713 top += angleTopOffset; 1714 this.setAngle({ 1715 position: 'top' 1716 }); 1717 } 1718 } 1719 if (top < 0) { 1720 top = 0; 1721 } 1722 const event = new PositionEvent(); 1723 event.left = left; 1724 event.top = top; 1725 this.emit('onBeforeAdjustPosition', event); 1726 main_core.Dom.adjust(this.popupContainer, { 1727 style: { 1728 top: `${event.top}px`, 1729 left: `${event.left}px` 1730 } 1731 }); 1732 } 1733 }, { 1734 key: "enterFullScreen", 1735 value: function enterFullScreen() { 1736 if (Popup.fullscreenStatus) { 1737 if (document.cancelFullScreen) { 1738 document.cancelFullScreen(); 1739 } else if (document.mozCancelFullScreen) { 1740 document.mozCancelFullScreen(); 1741 } else if (document.webkitCancelFullScreen) { 1742 document.webkitCancelFullScreen(); 1743 } 1744 } else { 1745 if (this.contentContainer.requestFullScreen) { 1746 this.contentContainer.requestFullScreen(); 1747 main_core.Event.bind(window, 'fullscreenchange', this.handleFullScreen); 1748 } else if (this.contentContainer.mozRequestFullScreen) { 1749 this.contentContainer.mozRequestFullScreen(); 1750 main_core.Event.bind(window, 'mozfullscreenchange', this.handleFullScreen); 1751 } else if (this.contentContainer.webkitRequestFullScreen) { 1752 this.contentContainer.webkitRequestFullScreen(); 1753 main_core.Event.bind(window, 'webkitfullscreenchange', this.handleFullScreen); 1754 } else { 1755 console.log('fullscreen mode is not supported'); 1756 } 1757 } 1758 } 1759 1760 /** 1761 * @private 1762 */ 1763 }, { 1764 key: "handleFullScreen", 1765 value: function handleFullScreen(event) { 1766 if (Popup.fullscreenStatus) { 1767 main_core.Event.unbind(window, 'fullscreenchange', this.handleFullScreen); 1768 main_core.Event.unbind(window, 'webkitfullscreenchange', this.handleFullScreen); 1769 main_core.Event.unbind(window, 'mozfullscreenchange', this.handleFullScreen); 1770 Popup.fullscreenStatus = false; 1771 if (!this.isDestroyed()) { 1772 main_core.Dom.removeClass(this.contentContainer, 'popup-window-fullscreen'); 1773 this.emit('onFullscreenLeave'); 1774 this.adjustPosition(); 1775 } 1776 } else { 1777 Popup.fullscreenStatus = true; 1778 if (!this.isDestroyed()) { 1779 main_core.Dom.addClass(this.contentContainer, 'popup-window-fullscreen'); 1780 this.emit('onFullscreenEnter'); 1781 this.adjustPosition(); 1782 } 1783 } 1784 } 1785 1786 /** 1787 * @private 1788 */ 1789 }, { 1790 key: "handleCloseIconClick", 1791 value: function handleCloseIconClick(event) { 1792 this.tryCloseByEvent(event); 1793 event.stopPropagation(); 1794 } 1795 1796 /** 1797 * @private 1798 */ 1799 }, { 1800 key: "handleContainerClick", 1801 value: function handleContainerClick(event) { 1802 event.stopPropagation(); 1803 } 1804 }, { 1805 key: "handleResizeWindow", 1806 value: 1807 /** 1808 * @private 1809 */ 1810 function handleResizeWindow() { 1811 if (this.isShown()) { 1812 this.adjustPosition(); 1813 if (this.overlay !== null) { 1814 this.resizeOverlay(); 1815 } 1816 } 1817 } 1818 1819 /** 1820 * @private 1821 */ 1822 }, { 1823 key: "handleMove", 1824 value: function handleMove(offsetX, offsetY, pageX, pageY) { 1825 let left = parseInt(this.popupContainer.style.left, 10) + offsetX; 1826 let top = parseInt(this.popupContainer.style.top, 10) + offsetY; 1827 if (main_core.Type.isObject(this.params.draggable) && this.params.draggable.restrict) { 1828 // Left side 1829 if (left < 0) { 1830 left = 0; 1831 } 1832 let scrollWidth; 1833 let scrollHeight; 1834 if (this.isTargetDocumentBody()) { 1835 scrollWidth = document.documentElement.scrollWidth; 1836 scrollHeight = document.documentElement.scrollHeight; 1837 } else { 1838 scrollWidth = this.getTargetContainer().scrollWidth; 1839 scrollHeight = this.getTargetContainer().scrollHeight; 1840 } 1841 1842 // Right side 1843 const floatWidth = this.popupContainer.offsetWidth; 1844 const floatHeight = this.popupContainer.offsetHeight; 1845 if (left > scrollWidth - floatWidth) { 1846 left = scrollWidth - floatWidth; 1847 } 1848 if (top > scrollHeight - floatHeight) { 1849 top = scrollHeight - floatHeight; 1850 } 1851 1852 // Top side 1853 if (top < 0) { 1854 top = 0; 1855 } 1856 } 1857 this.popupContainer.style.left = `${left}px`; 1858 this.popupContainer.style.top = `${top}px`; 1859 } 1860 1861 /** 1862 * @private 1863 */ 1864 }, { 1865 key: "handleDocumentMouseMove", 1866 value: 1867 /** 1868 * @private 1869 */ 1870 function handleDocumentMouseMove(event) { 1871 if (this.dragPageX === event.pageX && this.dragPageY === event.pageY) { 1872 return; 1873 } 1874 this.dragOptions.callback(event.pageX - this.dragPageX, event.pageY - this.dragPageY, event.pageX, event.pageY); 1875 this.dragPageX = event.pageX; 1876 this.dragPageY = event.pageY; 1877 if (!this.dragged) {
1878 this.emit(`on${this.dragOptions.eventName}Start`, new main_core_events.BaseEvent({ 1879 compatData: [this] 1880 })); 1881 this.dragged = true; 1882 } 1883 this.emit(`on${this.dragOptions.eventName}`, new main_core_events.BaseEvent({ 1884 compatData: [this] 1885 })); 1886 } 1887 1888 /** 1889 * @private 1890 */ 1891 }, { 1892 key: "handleDocumentMouseUp", 1893 value: function handleDocumentMouseUp(event) { 1894 if (document.body.releaseCapture) { 1895 document.body.releaseCapture(); 1896 } 1897 main_core.Event.unbind(document, 'mousemove', this.handleDocumentMouseMove); 1898 main_core.Event.unbind(document, 'mouseup', this.handleDocumentMouseUp); 1899 document.body.ondrag = null; 1900 document.body.onselectstart = null; 1901 document.body.style.cursor = ''; 1902 document.body.style.MozUserSelect = ''; 1903 this.popupContainer.style.MozUserSelect = ''; 1904 this.emit(`on${this.dragOptions.eventName}End`, new main_core_events.BaseEvent({ 1905 compatData: [this] 1906 })); 1907 this.dragged = false; 1908 event.preventDefault(); 1909 } 1910 }], [{ 1911 key: "setOptions", 1912 value: function setOptions(options) { 1913 if (!main_core.Type.isPlainObject(options)) { 1914 return; 1915 } 1916 for (let option in options) { 1917 this.options[option] = options[option]; 1918 } 1919 } 1920 }, { 1921 key: "getOption", 1922 value: function getOption(option, defaultValue) { 1923 if (!main_core.Type.isUndefined(this.options[option])) { 1924 return this.options[option]; 1925 } 1926 if (!main_core.Type.isUndefined(defaultValue)) { 1927 return defaultValue; 1928 } 1929 return this.defaultOptions[option]; 1930 } 1931 }, { 1932 key: "shouldUseFocusTrapByDefault", 1933 value: function shouldUseFocusTrapByDefault() { 1934 if (!ui_a11y.AccessibilitySettings.useFocusTrapInDialogs()) { 1935 return false; 1936 } 1937 const activeElement = ui_a11y.FocusNavigator.getActiveElement(); 1938 const nonTextInputTypes = new Set(['checkbox', 'radio', 'range', 'color', 'file', 'image', 'button', 'submit', 'reset']); 1939 if (activeElement === null) { 1940 return true; 1941 } 1942 const isTextInput = activeElement.tagName === 'TEXTAREA' || activeElement.tagName === 'INPUT' && !nonTextInputTypes.has(activeElement.type) || activeElement.isContentEditable; 1943 return !isTextInput; 1944 } 1945 }]); 1946 }(main_core_events.EventEmitter); 1947 _Popup = Popup; 1948 function _initFocusTrap(options) { 1949 if (options === false || main_core.Type.isNil(options) && !_Popup.shouldUseFocusTrapByDefault()) { 1950 return; 1951 } 1952 const defaultOptions = { 1953 initialFocus: ['[data-autofocus]', 'container'], 1954 isolateOutside: this.isModal() 1955 }; 1956 const focusTrapOptions = main_core.Type.isPlainObject(options) ? options : {}; 1957 _classPrivateFieldSet$1(_focusTrap, this, new ui_a11y.FocusTrap(this.popupContainer, { 1958 ...defaultOptions, 1959 ...focusTrapOptions 1960 })); 1961 if (this.isModal()) { 1962 main_core.Dom.attr(this.overlay.element, 'data-focus-trap', _classPrivateFieldGet$1(_focusTrap, this).getId()); 1963 } 1964 } 1965 function _disableTargetScroll() { 1966 const target = this.getTargetContainer(); 1967 let popups = disabledScrolls.get(target); 1968 if (!popups) { 1969 popups = new Set(); 1970 disabledScrolls.set(target, popups); 1971 } 1972 popups.add(this); 1973 main_core.Dom.addClass(target, 'popup-window-disable-scroll'); 1974 } 1975 function _enableTargetScroll() { 1976 const target = this.getTargetContainer(); 1977 const popups = disabledScrolls.get(target) || null; 1978 if (popups) { 1979 popups.delete(this); 1980 } 1981 if (popups === null || popups.size === 0) { 1982 main_core.Dom.removeClass(target, 'popup-window-disable-scroll'); 1983 } 1984 } 1985 function _startDrag(event, options) { 1986 options = options || {}; 1987 if (main_core.Type.isStringFilled(options.cursor)) { 1988 this.dragOptions.cursor = options.cursor; 1989 } 1990 if (main_core.Type.isStringFilled(options.eventName)) { 1991 this.dragOptions.eventName = options.eventName; 1992 } 1993 if (main_core.Type.isFunction(options.callback)) { 1994 this.dragOptions.callback = options.callback; 1995 } 1996 this.dragPageX = event.pageX; 1997 this.dragPageY = event.pageY; 1998 this.dragged = false; 1999 main_core.Event.bind(document, 'mousemove', this.handleDocumentMouseMove); 2000 main_core.Event.bind(document, 'mouseup', this.handleDocumentMouseUp); 2001 if (document.body.setCapture) { 2002 document.body.setCapture(); 2003 } 2004 document.body.ondrag = () => false;
2005 document.body.onselectstart = () => false; 2006 document.body.style.cursor = this.dragOptions.cursor; 2007 document.body.style.MozUserSelect = 'none'; 2008 this.popupContainer.style.MozUserSelect = 'none'; 2009 if (this.shouldFrontOnShow()) { 2010 this.bringToFront(); 2011 } 2012 event.preventDefault(); 2013 } 2014 /** 2015 * @private 2016 */ 2017 babelHelpers.defineProperty(Popup, "options", {}); 2018 /** 2019 * @private 2020 */ 2021 babelHelpers.defineProperty(Popup, "defaultOptions", { 2022 // left offset for popup about target 2023 angleLeftOffset: 40, 2024 // when popup position is 'top' offset distance between popup body and target node 2025 positionTopXOffset: -11, 2026 // offset distance between popup body and target node if use angle, sum with positionTopXOffset 2027 angleTopOffset: 10, 2028 popupZindex: 1000, 2029 popupOverlayZindex: 1100, 2030 angleMinLeft: 10, 2031 angleMaxLeft: 30, 2032 angleMinRight: 10, 2033 angleMaxRight: 30, 2034 angleMinBottom: 23, 2035 angleMaxBottom: 25, 2036 angleMinTop: 23, 2037 angleMaxTop: 25, 2038 offsetLeft: 0, 2039 offsetTop: 0 2040 }); 2041 let escCallbackIndex = -1; 2042 let escCallback = null; 2043 function checkEscPressed(zIndex, callback) { 2044 if (zIndex === false) { 2045 if (escCallback && escCallback.length > 0) { 2046 for (let i = 0; i < escCallback.length; i++) { 2047 escCallback[i](); 2048 } 2049 escCallback = null; 2050 escCallbackIndex = -1; 2051 } 2052 } else { 2053 if (escCallback === null) { 2054 escCallback = []; 2055 escCallbackIndex = -1; 2056 setTimeout(() => { 2057 checkEscPressed(false); 2058 }, 10); 2059 } 2060 if (zIndex > escCallbackIndex) { 2061 escCallbackIndex = zIndex; 2062 escCallback = [callback]; 2063 } else if (zIndex === escCallbackIndex) { 2064 escCallback.push(callback); 2065 } 2066 } 2067 } 2068 2069 const aliases = { 2070 onSubMenuShow: { 2071 namespace: 'BX.Main.Menu.Item', 2072 eventName: 'SubMenu:onShow' 2073 }, 2074 onSubMenuClose: { 2075 namespace: 'BX.Main.Menu.Item', 2076 eventName: 'SubMenu:onClose' 2077 } 2078 }; 2079 const reEscape = /["'<>]/g; 2080 const escapeEntities = { 2081 '<': '<', 2082 '>': '>', 2083 "'": ''', 2084 '"': '"' 2085 }; 2086 function encodeSafe(value) { 2087 if (main_core.Type.isString(value)) { 2088 return value.replaceAll(reEscape, item => escapeEntities[item]); 2089 } 2090 return value; 2091 } 2092 main_core_events.EventEmitter.registerAliases(aliases); 2093 class MenuItem extends main_core_events.EventEmitter { 2094 #items = []; 2095 #justFocused = false; 2096 constructor(itemOptions) { 2097 super(); 2098 this.setEventNamespace('BX.Main.Menu.Item'); 2099 const options = itemOptions || {}; 2100 this.options = options; 2101 this.id = options.id || main_core.Text.getRandom(); 2102 this.text = ''; 2103 this.allowHtml = false; 2104 if (main_core.Type.isStringFilled(options.html) || main_core.Type.isElementNode(options.html)) { 2105 this.text = options.html; 2106 this.allowHtml = true; 2107 } else if (main_core.Type.isStringFilled(options.text)) { 2108 this.text = options.text; 2109 if (/<[^>]+>/.test(this.text)) { 2110 // eslint-disable-next-line no-console 2111 console.warn('BX.Main.MenuItem: use "html" option for the html item content.', this.getText()); 2112 } 2113 } 2114 this.title = main_core.Type.isStringFilled(options.title) ? options.title : ''; 2115 this.delimiter = options.delimiter === true; 2116 this.href = main_core.Type.isStringFilled(options.href) ? options.href : null; 2117 this.target = main_core.Type.isStringFilled(options.target) ? options.target : null; 2118 this.dataset = main_core.Type.isPlainObject(options.dataset) ? options.dataset : null; 2119 this.className = main_core.Type.isStringFilled(options.className) ? options.className : null; 2120 this.menuShowDelay = main_core.Type.isNumber(options.menuShowDelay) ? options.menuShowDelay : 300; 2121 this.subMenuOffsetX = main_core.Type.isNumber(options.subMenuOffsetX) ? options.subMenuOffsetX : 4; 2122 this.#items = main_core.Type.isArray(options.items) ? options.items : []; 2123 this.disabled = options.disabled === true; 2124 this.cacheable = options.cacheable === true; 2125 this.focusable = this.delimiter !== true && options.focusable !== false; 2126 this.attrs = main_core.Type.isPlainObject(options.attrs) ? options.attrs : null; 2127 2128 /** 2129 * 2130 * @type {function|string} 2131 */ 2132 this.onclick = main_core.Type.isStringFilled(options.onclick) || main_core.Type.isFunction(options.onclick) ? options.onclick : null; 2133 this.subscribeFromOptions(options.events, aliases); 2134 2135 /** 2136 * 2137 * @type {Menu} 2138 */ 2139 this.menuWindow = null; 2140 2141 /** 2142 * 2143 * @type {Menu} 2144 */ 2145 this.subMenuWindow = null; 2146 2147 /** 2148 * 2149 * @type {{item: HTMLElement, text: HTMLElement}} 2150 */ 2151 this.layout = { 2152 item: null, 2153 text: null 2154 }; 2155 this.getLayout(); // compatibility 2156 2157 // compatibility 2158 // now use this.options 2159 this.events = {}; 2160 this.items = []; 2161 for (const property of Object.keys(options)) { 2162 if (!(property in this)) { 2163 this[property] = options[property]; 2164 } 2165 } 2166 } 2167 getLayout() { 2168 if (this.layout.item) { 2169 return this.layout; 2170 } 2171 if (this.delimiter) { 2172 if (main_core.Type.isStringFilled(this.getText())) { 2173 this.layout.item = main_core.Dom.create('span', { 2174 props: { 2175 className: ['popup-window-delimiter-section', this.className || ''].join(' ') 2176 }, 2177 attrs: { 2178 'aria-hidden': 'true' 2179 }, 2180 children: [this.layout.text = main_core.Tag.render` 2181 <span class="popup-window-delimiter-text">${this.allowHtml ? this.getText() : encodeSafe(this.getText())}</span> 2182 `] 2183 }); 2184 } else { 2185 this.layout.item = main_core.Tag.render`<span class="popup-window-delimiter" aria-hidden="true"></span>`;
2186 } 2187 } else { 2188 this.layout.item = main_core.Dom.create(this.href ? 'a' : 'span', { 2189 props: { 2190 className: ['menu-popup-item', this.className || 'menu-popup-no-icon', this.hasSubMenu() ? 'menu-popup-item-submenu' : ''].join(' ') 2191 }, 2192 attrs: { 2193 title: this.title, 2194 onclick: main_core.Type.isString(this.onclick) ? this.onclick : '', 2195 // compatibility 2196 target: this.target || '' 2197 }, 2198 dataset: this.dataset, 2199 events: main_core.Type.isFunction(this.onclick) ? { 2200 click: this.onItemClick.bind(this) 2201 } : null, 2202 children: [main_core.Dom.create('span', { 2203 props: { 2204 className: 'menu-popup-item-icon' 2205 } 2206 }), this.layout.text = main_core.Tag.render` 2207 <span class="menu-popup-item-text">${this.allowHtml ? this.getText() : encodeSafe(this.getText())}</span> 2208 `] 2209 }); 2210 if (main_core.Type.isPlainObject(this.attrs)) { 2211 main_core.Dom.attr(this.layout.item, this.attrs); 2212 } 2213 if (this.isFocusable()) { 2214 main_core.Dom.attr(this.layout.item, 'tabindex', '-1'); 2215 main_core.Dom.attr(this.layout.item, 'role', 'menuitem'); 2216 } else { 2217 main_core.Dom.attr(this.layout.item, 'aria-hidden', 'true'); 2218 } 2219 if (this.hasSubMenu()) { 2220 main_core.Dom.attr(this.layout.item, 'aria-haspopup', 'true'); 2221 main_core.Dom.attr(this.layout.item, 'aria-expanded', 'false'); 2222 } 2223 if (this.href) { 2224 this.layout.item.href = this.href; 2225 } 2226 if (this.isDisabled()) { 2227 this.disable(); 2228 } 2229 main_core.Event.bind(this.layout.item, ui_a11y.RESTORE_FOCUS_EVENT, this.#handleItemRestoreFocus.bind(this)); 2230 } 2231 main_core.Event.bind(this.layout.item, 'mouseenter', this.#handleItemMouseEnter.bind(this)); 2232 main_core.Event.bind(this.layout.item, 'mouseleave', this.#handleItemMouseLeave.bind(this)); 2233 main_core.Event.bind(this.layout.item, 'focusin', this.#handleItemFocus.bind(this)); 2234 return this.layout; 2235 } 2236 getContainer() { 2237 return this.getLayout().item; 2238 } 2239 getTextContainer() { 2240 return this.getLayout().text; 2241 } 2242 getText() { 2243 return this.text; 2244 } 2245 getTextContent() { 2246 if (main_core.Type.isString(this.text)) { 2247 return this.text; 2248 } 2249 if (main_core.Type.isElementNode(this.text)) { 2250 return this.text.textContent || ''; 2251 } 2252 return ''; 2253 } 2254 setText(text, allowHtml = false) { 2255 if (main_core.Type.isString(text) || main_core.Type.isElementNode(text)) { 2256 this.allowHtml = allowHtml; 2257 this.text = text; 2258 if (main_core.Type.isElementNode(text)) { 2259 main_core.Dom.clean(this.getTextContainer()); 2260 if (this.allowHtml) { 2261 main_core.Dom.append(text, this.getTextContainer()); 2262 } else { 2263 this.getTextContainer().innerHTML = encodeSafe(text.outerHTML); 2264 } 2265 } else { 2266 this.getTextContainer().innerHTML = this.allowHtml ? text : encodeSafe(text); 2267 } 2268 } 2269 } 2270 hasSubMenu() { 2271 return this.subMenuWindow !== null || this.#items.length > 0; 2272 } 2273 showSubMenu(trigger = null) { 2274 if (!this.getMenuWindow().isShown()) { 2275 return; 2276 } 2277 this.addSubMenu(this.#items); 2278 if (this.getSubMenu() !== null) { 2279 this.closeSiblings(trigger); 2280 this.closeChildren(trigger); 2281 if (!this.getSubMenu().isShown()) { 2282 this.emit('SubMenu:onShow'); 2283 this.getSubMenu().setLastInputModality(trigger); 2284 this.getSubMenu().show(); 2285 } 2286 main_core.Dom.attr(this.layout.item, 'aria-controls', this.getSubMenu().getId()); 2287 this.adjustSubMenu(); 2288 } 2289 } 2290 addSubMenu(items) { 2291 if (this.subMenuWindow !== null || !main_core.Type.isArray(items) || items.length === 0) { 2292 return null; 2293 } 2294 const rootMenuWindow = this.getMenuWindow().getRootMenuWindow() || this.getMenuWindow(); 2295 const rootOptions = { 2296 ...rootMenuWindow.params 2297 }; 2298 delete rootOptions.events; 2299 const subMenuOptions = main_core.Type.isPlainObject(rootMenuWindow.params.subMenuOptions) ? rootMenuWindow.params.subMenuOptions : {}; 2300 const options = { 2301 ...rootOptions, 2302 ...subMenuOptions 2303 }; 2304 2305 // Override root menu options 2306 options.autoHide = false;
2307 options.menuShowDelay = this.menuShowDelay; 2308 options.cacheable = this.isCacheable(); 2309 options.targetContainer = this.getMenuWindow().getPopupWindow().getTargetContainer(); 2310 options.bindOptions = { 2311 forceTop: true, 2312 forceLeft: true, 2313 forceBindPosition: true 2314 }; 2315 options.focusTrap = { 2316 initialFocus: false 2317 }; 2318 delete options.angle; 2319 delete options.overlay; 2320 this.subMenuWindow = new Menu(`popup-submenu-${this.id}`, this.layout.item, items, options); 2321 this.subMenuWindow.setParentMenuWindow(this.getMenuWindow()); 2322 this.subMenuWindow.setParentMenuItem(this); 2323 this.subMenuWindow.subscribe('onShow', this.#handleSubMenuShow.bind(this)); 2324 this.subMenuWindow.subscribe('onClose', this.#handleSubMenuClose.bind(this)); 2325 this.subMenuWindow.subscribe('onDestroy', this.#handleSubMenuDestroy.bind(this)); 2326 main_core.Dom.addClass(this.layout.item, 'menu-popup-item-submenu'); 2327 main_core.Dom.attr(this.layout.item, 'aria-haspopup', 'true'); 2328 return this.subMenuWindow; 2329 } 2330 closeSubMenu(trigger = null) { 2331 this.#clearSubMenuTimeout(); 2332 if (this.getSubMenu() !== null) { 2333 this.closeChildren(trigger); 2334 if (this.getSubMenu().isShown()) { 2335 this.emit('SubMenu:onClose'); 2336 }
2337 this.getSubMenu().setLastInputModality(trigger); 2338 this.getSubMenu().close(); 2339 } 2340 } 2341 closeSiblings(trigger = null) { 2342 const siblings = this.menuWindow.getMenuItems(); 2343 for (const sibling of siblings) { 2344 if (sibling !== this) { 2345 sibling.closeSubMenu(trigger); 2346 } 2347 } 2348 } 2349 closeChildren(trigger = null) { 2350 if (this.getSubMenu() !== null) { 2351 const children = this.getSubMenu().getMenuItems(); 2352 for (const child of children) { 2353 child.closeSubMenu(trigger); 2354 } 2355 } 2356 } 2357 destroySubMenu() { 2358 if (this.getSubMenu() !== null) { 2359 main_core.Dom.removeClass(this.layout.item, 'menu-popup-item-open menu-popup-item-submenu'); 2360 main_core.Dom.attr(this.layout.item, 'aria-haspopup', null); 2361 this.destroyChildren(); 2362 this.getSubMenu().destroy(); 2363 this.subMenuWindow = null; 2364 this.#items = []; 2365 } 2366 } 2367 destroyChildren() { 2368 if (this.getSubMenu() !== null) { 2369 const children = this.getSubMenu().getMenuItems(); 2370 for (const child of children) { 2371 child.destroySubMenu(); 2372 } 2373 } 2374 } 2375 adjustSubMenu() { 2376 if (this.getSubMenu() === null || !this.layout.item) { 2377 return; 2378 } 2379 const popupWindow = this.getSubMenu().getPopupWindow(); 2380 const itemRect = this.getBoundingClientRect(); 2381 let offsetLeft = itemRect.width + this.subMenuOffsetX; 2382 let offsetTop = itemRect.height + this.getPopupPadding(); 2383 let angleOffset = itemRect.height / 2 - this.getPopupPadding(); 2384 let anglePosition = 'left'; 2385 const popupWidth = popupWindow.getPopupContainer().offsetWidth; 2386 const popupHeight = popupWindow.getPopupContainer().offsetHeight; 2387 const popupBottom = itemRect.top + popupHeight; 2388 const targetContainer = this.getMenuWindow().getPopupWindow().getTargetContainer(); 2389 const isGlobalContext = this.getMenuWindow().getPopupWindow().isTargetDocumentBody(); 2390 const clientWidth = isGlobalContext ? document.documentElement.clientWidth : targetContainer.offsetWidth; 2391 const clientHeight = isGlobalContext ? document.documentElement.clientHeight : targetContainer.offsetHeight; 2392 2393 // let's try to fit a submenu to the browser viewport 2394 const exceeded = popupBottom - clientHeight; 2395 if (exceeded > 0) { 2396 let roundOffset = Math.ceil(exceeded / itemRect.height) * itemRect.height; 2397 if (roundOffset > itemRect.top) { 2398 // it cannot be higher than the browser viewport. 2399 roundOffset -= Math.ceil((roundOffset - itemRect.top) / itemRect.height) * itemRect.height; 2400 } 2401 if (itemRect.bottom > popupBottom - roundOffset) { 2402 // let's sync bottom boundaries. 2403 roundOffset -= itemRect.bottom - (popupBottom - roundOffset) + this.getPopupPadding(); 2404 } 2405 offsetTop += roundOffset; 2406 angleOffset += roundOffset; 2407 } 2408 if (itemRect.left + offsetLeft + popupWidth > clientWidth) { 2409 const left = itemRect.left - popupWidth - this.subMenuOffsetX; 2410 if (left > 0) { 2411 offsetLeft = -popupWidth - this.subMenuOffsetX; 2412 anglePosition = 'right'; 2413 } 2414 } 2415 popupWindow.setBindElement(this.layout.item); 2416 popupWindow.setOffset({ 2417 offsetLeft, 2418 offsetTop: -offsetTop 2419 }); 2420 popupWindow.setAngle({ 2421 position: anglePosition, 2422 offset: angleOffset 2423 }); 2424 popupWindow.adjustPosition(); 2425 } 2426 getBoundingClientRect() { 2427 const popup = this.getMenuWindow().getPopupWindow(); 2428 if (popup.isTargetDocumentBody()) { 2429 return this.layout.item.getBoundingClientRect(); 2430 } 2431 const rect = popup.getPositionRelativeToTarget(this.layout.item); 2432 const targetContainer = this.getMenuWindow().getPopupWindow().getTargetContainer(); 2433 return new DOMRect(rect.left - targetContainer.scrollLeft, rect.top - targetContainer.scrollTop, rect.width, rect.height); 2434 } 2435 getPopupPadding() { 2436 if (!main_core.Type.isNumber(this.popupPadding)) { 2437 if (this.subMenuWindow) { 2438 const menuContainer = this.subMenuWindow.layout.menuContainer; 2439 this.popupPadding = parseInt(main_core.Dom.style(menuContainer, 'paddingTop'), 10); 2440 } else { 2441 this.popupPadding = 0; 2442 } 2443 } 2444 return this.popupPadding; 2445 } 2446 getSubMenu() { 2447 return this.subMenuWindow; 2448 } 2449 getId() { 2450 return this.id; 2451 } 2452 setMenuWindow(menu) { 2453 this.menuWindow = menu; 2454 } 2455 getMenuWindow() { 2456 return this.menuWindow; 2457 } 2458 getMenuShowDelay() { 2459 return this.menuShowDelay; 2460 } 2461 enable() { 2462 this.disabled = false;
2463 main_core.Dom.removeClass(this.getContainer(), 'menu-popup-item-disabled'); 2464 main_core.Dom.attr(this.getContainer(), 'aria-disabled', null); 2465 } 2466 disable() { 2467 this.disabled = true; 2468 this.closeSubMenu(); 2469 main_core.Dom.addClass(this.getContainer(), 'menu-popup-item-disabled'); 2470 main_core.Dom.attr(this.getContainer(), 'aria-disabled', 'true'); 2471 } 2472 isDisabled() { 2473 return this.disabled; 2474 } 2475 isFocusable() { 2476 return this.focusable; 2477 } 2478 setCacheable(cacheable) { 2479 this.cacheable = cacheable !== false; 2480 } 2481 isCacheable() { 2482 return this.cacheable; 2483 } 2484 isDelimiter() { 2485 return this.delimiter; 2486 } 2487 focus(focusVisible = false) { 2488 if (this.isFocused() || this.isDelimiter() || !this.isFocusable()) { 2489 return; 2490 } 2491 this.focused = true; 2492 main_core.Dom.addClass(this.getContainer(), `--focus${focusVisible ? ' --focus-visible' : ''}`); 2493 main_core.Dom.attr(this.getContainer(), 'tabindex', '0'); 2494 if (this.getMenuWindow().getFocusTrap() !== null) { 2495 this.getContainer().focus({ 2496 preventScroll: !focusVisible 2497 }); 2498 } 2499 this.getMenuWindow().emit('Item:onFocus', { 2500 item: this 2501 }); 2502 } 2503 blur() { 2504 if (!this.isFocused() || this.isDelimiter() || !this.isFocusable()) { 2505 return; 2506 } 2507 this.focused = false; 2508 main_core.Dom.removeClass(this.getContainer(), '--focus --focus-visible'); 2509 main_core.Dom.attr(this.getContainer(), 'tabindex', '-1'); 2510 this.getMenuWindow().emit('Item:onBlur', { 2511 item: this 2512 }); 2513 } 2514 isFocused() { 2515 return this.focused; 2516 } 2517 2518 /** 2519 * @private 2520 */ 2521 onItemClick(event) { 2522 this.onclick.call(this.menuWindow, event, this); // compatibility 2523 } 2524 #handleItemFocus() { 2525 this.#justFocused = true; 2526 setTimeout(() => { 2527 this.#justFocused = false; 2528 }, 100); 2529 } 2530 #handleItemMouseEnter(mouseEvent) { 2531 if (this.getMenuWindow()?.shouldIgnoreMouseEnter() || this.#justFocused) { 2532 return; 2533 } 2534 const event = new main_core_events.BaseEvent({ 2535 data: { 2536 mouseEvent 2537 } 2538 }); 2539 main_core_events.EventEmitter.emit(this, 'onMouseEnter', event, { 2540 thisArg: this 2541 }); 2542 if (event.isDefaultPrevented()) { 2543 return; 2544 } 2545 this.focus(); 2546 this.#clearSubMenuTimeout(); 2547 if (this.hasSubMenu()) { 2548 this.subMenuTimeout = setTimeout(() => { 2549 this.showSubMenu('pointer'); 2550 }, this.menuShowDelay); 2551 } else { 2552 this.subMenuTimeout = setTimeout(() => { 2553 this.closeSiblings('pointer'); 2554 }, this.menuShowDelay); 2555 } 2556 } 2557 #handleItemMouseLeave(mouseEvent) { 2558 const event = new main_core_events.BaseEvent({ 2559 data: { 2560 mouseEvent 2561 } 2562 }); 2563 main_core_events.EventEmitter.emit(this, 'onMouseLeave', event, { 2564 thisArg: this 2565 }); 2566 if (event.isDefaultPrevented()) { 2567 return; 2568 } 2569 this.blur(); 2570 this.#clearSubMenuTimeout(); 2571 } 2572 #handleItemRestoreFocus(event) { 2573 event.preventDefault(); 2574 const hasFocus = this.getMenuWindow().getMenuItems().some(item => item.isFocused()); 2575 if (!hasFocus) { 2576 this.focus(ui_a11y.FocusMonitor.Instance.getLastInputModality() === 'keyboard'); 2577 } 2578 } 2579 #clearSubMenuTimeout() { 2580 if (this.subMenuTimeout) { 2581 clearTimeout(this.subMenuTimeout); 2582 } 2583 this.subMenuTimeout = null; 2584 } 2585 #handleSubMenuShow() { 2586 main_core.Dom.addClass(this.layout.item, 'menu-popup-item-open'); 2587 main_core.Dom.attr(this.layout.item, 'aria-expanded', 'true'); 2588 } 2589 #handleSubMenuClose() { 2590 main_core.Dom.removeClass(this.layout.item, 'menu-popup-item-open'); 2591 main_core.Dom.attr(this.layout.item, 'aria-expanded', 'false'); 2592 main_core.Dom.attr(this.layout.item, 'aria-controls', null); 2593 } 2594 #handleSubMenuDestroy() { 2595 this.#handleSubMenuClose(); 2596 this.subMenuWindow = null; 2597 } 2598 } 2599 2600 const collator = new Intl.Collator(undefined, { 2601 sensitivity: 'base' 2602 }); 2603 class MenuNavigation { 2604 #menu = null; 2605 #enabled = false; 2606 #onKeyDownHandler = null; 2607 #searchBuffer = ''; 2608 #resetTimer = null; 2609 #onTab = null; 2610 #initialFocusPosition = 'first'; 2611 constructor(menu, options = {}) { 2612 this.#menu = menu; 2613 this.#menu.subscribe('onShow', this.#handleMenuShow.bind(this)); 2614 this.#menu.subscribe('onDestroy', this.#handleMenuDestroy.bind(this));
2615 this.#onKeyDownHandler = this.#handleKeyDown.bind(this); 2616 this.#onTab = main_core.Type.isFunction(options.onTab) ? options.onTab : null; 2617 this.setInitialFocusPosition(options.initialFocusPosition); 2618 } 2619 getMenu() { 2620 return this.#menu; 2621 } 2622 enable() { 2623 if (!this.isEnabled()) { 2624 this.bindEvents(); 2625 } 2626 this.#enabled = true; 2627 } 2628 disable() { 2629 if (this.isEnabled()) { 2630 this.unbindEvents(); 2631 } 2632 this.#enabled = false; 2633 } 2634 isEnabled() { 2635 return this.#enabled; 2636 } 2637 bindEvents() { 2638 main_core.Event.bind(this.getMenu().getMenuContainer(), 'keydown', this.#onKeyDownHandler); 2639 } 2640 unbindEvents() { 2641 main_core.Event.unbind(this.getMenu().getMenuContainer(), 'keydown', this.#onKeyDownHandler); 2642 } 2643 setInitialFocusPosition(focusPosition) { 2644 if (focusPosition === 'first' || focusPosition === 'last') { 2645 this.#initialFocusPosition = focusPosition; 2646 } 2647 } 2648 #handleMenuShow() { 2649 this.enable(); 2650 if (this.#menu.getParentMenuWindow() === null) { 2651 if (ui_a11y.FocusMonitor.Instance.getLastInputModality() === 'keyboard' && this.#menu.getFocusTrap() !== null) { 2652 if (this.#initialFocusPosition === 'last') { 2653 this.focusLast(); 2654 } else { 2655 this.focusFirst(); 2656 } 2657 } 2658 } else if (this.#menu.getLastInputModal() === 'keyboard') { 2659 this.focusFirst(); 2660 } 2661 } 2662 #handleMenuDestroy() { 2663 this.disable(); 2664 this.#menu = null; 2665 } 2666 #handleKeyDown(event) { 2667 if (!this.getMenu().isShown()) { 2668 return; 2669 } 2670 if (event.metaKey || event.ctrlKey || event.altKey) { 2671 return; 2672 } 2673 const target = event.target; 2674 if (target?.tagName === 'TEXTAREA' || target instanceof HTMLInputElement) { 2675 return; 2676 } 2677 event.preventDefault(); 2678 switch (event.key) { 2679 case 'ArrowDown': 2680 { 2681 this.focusNext(); 2682 break; 2683 } 2684 case 'ArrowUp': 2685 { 2686 this.focusPrevious(); 2687 break; 2688 } 2689 case 'ArrowLeft': 2690 { 2691 const focusedItem = this.getMenu().getFocusedItem(); 2692 const parentItem = focusedItem?.getMenuWindow()?.getParentMenuItem(); 2693 if (parentItem) { 2694 parentItem.focus(true); 2695 parentItem.closeSubMenu('keyboard'); 2696 } 2697 break; 2698 } 2699 case 'ArrowRight': 2700 { 2701 this.#openSubMenuByKeyboard(this.getMenu().getFocusedItem()); 2702 break; 2703 } 2704 case 'Home': 2705 case 'PageUp': 2706 { 2707 this.focusFirst(); 2708 break; 2709 } 2710 case 'End': 2711 case 'PageDown': 2712 { 2713 this.focusLast(); 2714 break; 2715 } 2716 case ' ': 2717 case 'Enter': 2718 case 'Space': 2719 { 2720 const focusedItem = this.getMenu().getFocusedItem(); 2721 if (focusedItem) { 2722 if (focusedItem.hasSubMenu()) { 2723 this.#openSubMenuByKeyboard(focusedItem); 2724 } else { 2725 focusedItem.getContainer().click(); 2726 } 2727 } 2728 break; 2729 } 2730 case 'Tab': 2731 { 2732 if (this.#onTab === null) { 2733 const rootMenuWindow = this.getMenu().getRootMenuWindow() || this.getMenu(); 2734 rootMenuWindow.close(); 2735 } else { 2736 this.#onTab(event, this.#menu); 2737 } 2738 break; 2739 } 2740 default: 2741 { 2742 if (this.#isTypeaheadEvent(event)) { 2743 this.#searchBuffer += event.key; 2744 this.focusByText(this.#searchBuffer); 2745 clearTimeout(this.#resetTimer); 2746 this.#resetTimer = setTimeout(() => { 2747 this.#searchBuffer = ''; 2748 }, 200); 2749 } 2750 break; 2751 } 2752 } 2753 } 2754 #openSubMenuByKeyboard(item) { 2755 if (!item || !item.hasSubMenu()) { 2756 return; 2757 } 2758 if (item.getSubMenu()?.isShown()) { 2759 item.getSubMenu().getNavigation().focusFirst(); 2760 } else { 2761 item.showSubMenu('keyboard'); 2762 } 2763 item.blur(); 2764 } 2765 #isTypeaheadEvent(event) { 2766 if (event.key === ' ' && this.#searchBuffer.length > 0) { 2767 return true; 2768 } 2769 return event.key.length === 1 && /^[\p{Letter}\p{Number}]$/u.test(event.key); 2770 } 2771 focusByText(text) { 2772 const items = this.getItems(); 2773 const focusedItem = this.getMenu().getFocusedItem(); 2774 const normalizedText = text.toLowerCase(); 2775 const matches = items.filter(item => { 2776 const word = item.getTextContent().trim().toLowerCase().slice(0, Math.max(0, normalizedText.length)); 2777 return collator.compare(normalizedText, word) === 0; 2778 }); 2779 if (matches.length === 0) { 2780 return null; 2781 } 2782 const focusedMatchIndex = matches.indexOf(focusedItem); 2783 if (focusedMatchIndex >= 0) { 2784 const item = matches[(focusedMatchIndex + 1) % matches.length]; 2785 item.focus(true); 2786 return item; 2787 } 2788 const focusedIndex = items.indexOf(focusedItem); 2789 const nextMatch = matches.find(item => items.indexOf(item) > focusedIndex) ?? matches[0]; 2790 nextMatch.focus(true); 2791 return nextMatch; 2792 } 2793 focusNext(looped = true) { 2794 const focusedItem = this.getMenu().getFocusedItem(); 2795 const items = this.getItems(); 2796 if (items.length === 0) { 2797 return null; 2798 } 2799 if (!focusedItem) { 2800 items[0].focus(true); 2801 return items[0]; 2802 } 2803 const position = this.getMenuItemPosition(focusedItem.id); 2804 if (position === -1) { 2805 items[0].focus(true); 2806 return items[0]; 2807 } 2808 if (position + 1 < items.length) { 2809 const nextPosition = position + 1; 2810 items[nextPosition].focus(true); 2811 return items[nextPosition]; 2812 } 2813 if (looped) { 2814 items[0].focus(true); 2815 return items[0]; 2816 } 2817 return null; 2818 } 2819 focusPrevious(looped = true) { 2820 const focusedItem = this.getMenu().getFocusedItem(); 2821 const items = this.getItems(); 2822 if (items.length === 0) { 2823 return null; 2824 } 2825 if (!focusedItem) { 2826 items[items.length - 1].focus(true); 2827 return items[items.length - 1]; 2828 } 2829 const position = this.getMenuItemPosition(focusedItem.id); 2830 if (position === -1) { 2831 items[items.length - 1].focus(true); 2832 return items[items.length - 1]; 2833 } 2834 if (position - 1 >= 0) { 2835 const previousPosition = position - 1; 2836 items[previousPosition].focus(true); 2837 return items[previousPosition]; 2838 } 2839 if (looped) { 2840 const lastPosition = items.length - 1; 2841 items[lastPosition].focus(true); 2842 return items[lastPosition]; 2843 } 2844 return null; 2845 } 2846 focusFirst() { 2847 const items = this.getItems(); 2848 if (items.length > 0) { 2849 items[0].focus(true); 2850 return items[0]; 2851 } 2852 return null; 2853 } 2854 focusLast() { 2855 const items = this.getItems(); 2856 if (items.length > 0) { 2857 items[items.length - 1].focus(true); 2858 return items[items.length - 1]; 2859 } 2860 return null; 2861 } 2862 getItems() { 2863 return this.getMenu().getMenuItems().filter(item => { 2864 return item.isFocusable() && ui_a11y.InteractivityChecker.isVisible(item.getContainer()); 2865 }); 2866 } 2867 getMenuItemPosition(itemId) { 2868 const items = this.getItems(); 2869 for (const [i, item] of items.entries()) { 2870 if (item.id && item.id === itemId) { 2871 return i; 2872 } 2873 } 2874 return -1; 2875 } 2876 } 2877 2878 function _callSuper(t, o, e) { return o = babelHelpers.getPrototypeOf(o
2878), babelHelpers.possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, [], babelHelpers.getPrototypeOf(t).constructor) : o.apply(t, e)); } 2879 function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } 2880 function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); } 2881 function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } 2882 function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } 2883 function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); } 2884 function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } 2885 function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } 2886 /** 2887 * @memberof BX.Main 2888 */ 2889 var _navigation = /*#__PURE__*/new WeakMap(); 2890 var _focusedItem = /*#__PURE__*/new WeakMap(); 2891 var _lastInputModality = /*#__PURE__*/new WeakMap(); 2892 var _ignoreMouseEnter = /*#__PURE__*/new WeakMap(); 2893 var _Menu_brand = /*#__PURE__*/new WeakSet(); 2894 let Menu = /*#__PURE__*/function (_EventEmitter) { 2895 function Menu(_options) { 2896 var _this; 2897 babelHelpers.classCallCheck(this, Menu); 2898 _this = _callSuper(this, Menu); 2899 /** 2900 * @private 2901 */ 2902 _classPrivateMethodInitSpec(_this, _Menu_brand); 2903 _classPrivateFieldInitSpec(_this, _navigation, null); 2904 _classPrivateFieldInitSpec(_this, _focusedItem, null); 2905 _classPrivateFieldInitSpec(_this, _lastInputModality, null); 2906 _classPrivateFieldInitSpec(_this, _ignoreMouseEnter, true); 2907 _this.setEventNamespace('BX.Main.Menu'); 2908 let [_id, bindElement, menuItems, params] = arguments; 2909 if (main_core.Type.isPlainObject(_options) && !bindElement && !menuItems && !params) { 2910 params = _options; 2911 params.compatibleMode = false; 2912 _id = _options.id; 2913 bindElement = _options.bindElement; 2914 menuItems = _options.items; 2915 if (!main_core.Type.isStringFilled(_id)) { 2916 _id = `menu-popup-${main_core.Text.getRandom()}`; 2917 } 2918 } 2919 _this.emit('onInit', { 2920 id: _id, 2921 bindElement, 2922 menuItems, 2923 params 2924 }); 2925 _this.id = _id; 2926 _this.bindElement = bindElement; 2927 2928 /** 2929 * 2930 * @type {MenuItem[]} 2931 */ 2932 _this.menuItems = []; 2933 _this.itemsContainer = null; 2934 _this.params = params && typeof params === 'object' ? params : {}; 2935 _this.parentMenuWindow = null; 2936 _this.parentMenuItem = null; 2937 if (menuItems && main_core.Type.isArray(menuItems)) { 2938 for (const menuItem of menuItems) { 2939 _this.addMenuItemInternal(menuItem, null); 2940 } 2941 } 2942 _this.layout = { 2943 menuContainer: null, 2944 itemsContainer: null 2945 }; 2946 _this.popupWindow = _assertClassBrand(_Menu_brand, _this, _createPopup).call(_this); 2947 _classPrivateFieldSet(_navigation, _this, new MenuNavigation(_this, params?.navigationOptions)); 2948 _this.subscribe('Item:onFocus', _assertClassBrand(_Menu_brand, _this, _handleItemFocus).bind(_this)); 2949 _this.subscribe('Item:onBlur', _assertClassBrand(_Menu_brand, _this, _handleItemBlur).bind(_this)); 2950 return _this; 2951 } 2952 babelHelpers.inherits(Menu, _EventEmitter); 2953 return babelHelpers.createClass(Menu, [{ 2954 key: "getPopupWindow", 2955 value: function getPopupWindow() { 2956 return this.popupWindow; 2957 } 2958 }, { 2959 key: "show", 2960 value: function show() { 2961 this.getPopupWindow().show(); 2962 } 2963 }, { 2964 key: "close", 2965 value: function close() { 2966 this.getPopupWindow().close(); 2967 } 2968 }, { 2969 key: "destroy", 2970 value: function destroy() { 2971 this.getPopupWindow().destroy(); 2972 } 2973 }, { 2974 key: "toggle", 2975 value: function toggle() { 2976 if (this.getPopupWindow().isShown()) { 2977 this.close(); 2978 } else { 2979 this.show(); 2980 } 2981 } 2982 }, { 2983 key: "isShown", 2984 value: function isShown() { 2985 return this.getPopupWindow().isShown(); 2986 } 2987 }, { 2988 key: "getId", 2989 value: function getId() { 2990 return this.id; 2991 } 2992 }, { 2993 key: "getNavigation", 2994 value: function getNavigation() { 2995 return _classPrivateFieldGet(_navigation, this); 2996 } 2997 }, { 2998 key: "getFocusTrap", 2999 value: function getFocusTrap() { 3000 return this.getPopupWindow().getFocusTrap(); 3001 } 3002 }, { 3003 key: "setLastInputModality", 3004 value: function setLastInputModality(modality) { 3005 _classPrivateFieldSet(_lastInputModality, this, modality); 3006 } 3007 }, { 3008 key: "getLastInputModal", 3009 value: function getLastInputModal() { 3010 return _classPrivateFieldGet(_lastInputModality, this); 3011 } 3012 }, { 3013 key: "shouldIgnoreMouseEnter", 3014 value: function shouldIgnoreMouseEnter() { 3015 return _classPrivateFieldGet(_ignoreMouseEnter, this); 3016 } 3017 }, { 3018 key: "containsTarget", 3019 value: 3020 /** 3021 * @private 3022 */ 3023 function containsTarget(target) { 3024 const el = this.getPopupWindow().getPopupContainer(); 3025 if (this.getPopupWindow().isShown() && (target === el || el.contains(target))) { 3026 return true; 3027 } 3028 return this.getMenuItems().some(item => { 3029 return item.getSubMenu() && item.getSubMenu().containsTarget(target); 3030 }); 3031 } 3032 }, { 3033 key: "setParentMenuWindow", 3034 value: function setParentMenuWindow(parentMenu) { 3035 if (parentMenu instanceof Menu) { 3036 this.parentMenuWindow = parentMenu; 3037 } 3038 } 3039 }, { 3040 key: "getParentMenuWindow", 3041 value: function getParentMenuWindow() { 3042 return this.parentMenuWindow; 3043 } 3044 }, { 3045 key: "isRootMenu", 3046 value: function isRootMenu() { 3047 return this.getParentMenuWindow() === null; 3048 } 3049 }, {
3050 key: "getRootMenuWindow", 3051 value: function getRootMenuWindow() { 3052 let root = null; 3053 let parent = this.getParentMenuWindow(); 3054 while (parent !== null) { 3055 root = parent; 3056 parent = parent.getParentMenuWindow(); 3057 } 3058 return root; 3059 } 3060 }, { 3061 key: "setParentMenuItem", 3062 value: function setParentMenuItem(parentItem) { 3063 if (parentItem instanceof MenuItem) { 3064 this.parentMenuItem = parentItem; 3065 } 3066 } 3067 }, { 3068 key: "getParentMenuItem", 3069 value: function getParentMenuItem() { 3070 return this.parentMenuItem; 3071 } 3072 }, { 3073 key: "addMenuItem", 3074 value: function addMenuItem(menuItemJson, targetItemId) { 3075 const menuItem = this.addMenuItemInternal(menuItemJson, targetItemId); 3076 if (!menuItem) { 3077 return null; 3078 } 3079 const itemLayout = menuItem.getLayout(); 3080 const targetItem = this.getMenuItem(targetItemId); 3081 if (targetItem === null) { 3082 this.itemsContainer.appendChild(itemLayout.item); 3083 } else { 3084 const targetLayout = targetItem.getLayout(); 3085 this.itemsContainer.insertBefore(itemLayout.item, targetLayout.item); 3086 } 3087 return menuItem; 3088 } 3089 3090 /** 3091 * @private 3092 */ 3093 }, { 3094 key: "addMenuItemInternal", 3095 value: function addMenuItemInternal(menuItemJson, targetItemId) { 3096 if (!menuItemJson || !menuItemJson.delimiter && !main_core.Type.isStringFilled(menuItemJson.text) && !main_core.Type.isStringFilled(menuItemJson.html) && !main_core.Type.isElementNode(menuItemJson.html) || menuItemJson.id && this.getMenuItem(menuItemJson.id) !== null) { 3097 return null; 3098 } 3099 if (main_core.Type.isNumber(this.params.menuShowDelay)) { 3100 menuItemJson.menuShowDelay = this.params.menuShowDelay; 3101 } 3102 const menuItem = new MenuItem(menuItemJson); 3103 menuItem.setMenuWindow(this); 3104 const position = this.getMenuItemPosition(targetItemId); 3105 if (position >= 0) { 3106 this.menuItems.splice(position, 0, menuItem); 3107 } else { 3108 this.menuItems.push(menuItem); 3109 } 3110 return menuItem; 3111 } 3112 }, { 3113 key: "removeMenuItem", 3114 value: function removeMenuItem(itemId, options = { 3115 destroyEmptyPopup: true 3116 }) { 3117 const item = this.getMenuItem(itemId); 3118 if (!item) { 3119 return; 3120 } 3121 for (let position = 0; position < this.menuItems.length; position++) { 3122 if (this.menuItems[position] === item) { 3123 item.destroySubMenu(); 3124 this.menuItems.splice(position, 1); 3125 break; 3126 } 3127 } 3128 if (this.menuItems.length === 0) { 3129 const menuWindow = item.getMenuWindow(); 3130 if (menuWindow) { 3131 const parentMenuItem = menuWindow.getParentMenuItem(); 3132 if (parentMenuItem) { 3133 parentMenuItem.destroySubMenu(); 3134 } else if (options.destroyEmptyPopup) { 3135 menuWindow.destroy(); 3136 } 3137 } 3138 } 3139 item.layout.item.parentNode.removeChild(item.layout.item); 3140 item.layout = { 3141 item: null, 3142 text: null 3143 }; 3144 } 3145 }, { 3146 key: "getMenuItem", 3147 value: function getMenuItem(itemId) { 3148 for (let i = 0; i < this.menuItems.length; i++) { 3149 if (this.menuItems[i].id && this.menuItems[i].id === itemId) { 3150 return this.menuItems[i]; 3151 } 3152 } 3153 return null; 3154 } 3155 }, { 3156 key: "getMenuItems", 3157 value: function getMenuItems() { 3158 return this.menuItems; 3159 } 3160 }, { 3161 key: "getMenuItemPosition", 3162 value: function getMenuItemPosition(itemId) { 3163 if (itemId) { 3164 for (let i = 0; i < this.menuItems.length; i++) { 3165 if (this.menuItems[i].id && this.menuItems[i].id === itemId) { 3166 return i; 3167 } 3168 } 3169 } 3170 return -1; 3171 } 3172 }, { 3173 key: "getMenuContainer", 3174 value: function getMenuContainer() { 3175 return this.getPopupWindow().getPopupContainer(); 3176 } 3177 }, { 3178 key: "getFocusedItem", 3179 value: function getFocusedItem() { 3180 return _classPrivateFieldGet(_focusedItem, this); 3181 } 3182 }, { 3183 key: "clearFocus", 3184 value: function clearFocus() { 3185 if (_classPrivateFieldGet(_focusedItem, this)) { 3186 _classPrivateFieldGet(_focusedItem, this).blur(); 3187 _classPrivateFieldSet(_focusedItem, this, null); 3188 } 3189 } 3190 }]); 3191 }(main_core_events.EventEmitter); 3192 function _createPopup() { 3193 const domItems = []; 3194 for (let i = 0; i < this.menuItems.length; i++) { 3195 const item = this.menuItems[i]; 3196 const itemLayout = item.getLayout(); 3197 domItems.push(itemLayout.item); 3198 } 3199 const defaults = { 3200 closeByEsc: true, 3201 angle: false, 3202 autoHide: true, 3203 offsetTop: 1, 3204 offsetLeft: 0, 3205 animation: 'fading' 3206 }; 3207 const options = Object.assign(defaults, this.params); 3208 3209 // Override user params 3210 options.noAllPaddings = true; 3211 options.darkMode = false;
3212 options.autoHideHandler = _assertClassBrand(_Menu_brand, this, _handleAutoHide).bind(this); 3213 options.role = 'menu'; 3214 if (main_core.Type.isNil(options.focusTrap) && Popup.shouldUseFocusTrapByDefault()) { 3215 options.focusTrap = { 3216 initialFocus: 'container' 3217 }; 3218 } 3219 this.layout.itemsContainer = main_core.Tag.render` 3220 <div class="menu-popup-items" role="presentation">${domItems}</div> 3221 `; 3222 this.layout.menuContainer = main_core.Tag.render` 3223 <div class="menu-popup" role="presentation">${this.layout.itemsContainer}</div> 3224 `; 3225 this.itemsContainer = this.layout.itemsContainer; 3226 options.content = this.layout.menuContainer; 3227 3228 // Make internal event handlers first in the queue. 3229 options.events = { 3230 onBeforeShow: _assertClassBrand(_Menu_brand, this, _handlePopupBeforeShow).bind(this), 3231 onShow: _assertClassBrand(_Menu_brand, this, _handlePopupShow).bind(this), 3232 onAfterShow: _assertClassBrand(_Menu_brand, this, _handlePopupAfterShow).bind(this), 3233 onClose: _assertClassBrand(_Menu_brand, this, _handlePopupClose).bind(this), 3234 onDestroy: _assertClassBrand(_Menu_brand, this, _handlePopupDestroy).bind(this) 3235 }; 3236 const id = options.compatibleMode === false ? this.getId() : `menu-popup-${this.getId()}`; 3237 const popup = new Popup(id, this.bindElement, options); 3238 if (this.params && this.params.events) { 3239 popup.subscribeFromOptions(this.params.events); 3240 } 3241 return popup; 3242 } 3243 function _handlePopupBeforeShow() { 3244 this.emit('onBeforeShow'); 3245 _classPrivateFieldSet(_ignoreMouseEnter, this, true); 3246 } 3247 function _handlePopupShow() { 3248 this.emit('onShow'); 3249 } 3250 function _handlePopupAfterShow() { 3251 this.emit('onAfterShow'); 3252 _classPrivateFieldSet(_ignoreMouseEnter, this, false); 3253 } 3254 function _handlePopupClose() { 3255 this.emit('onClose'); 3256 for (let i = 0; i < this.menuItems.length; i++) { 3257 const item = this.menuItems[i]; 3258 item.blur(); 3259 item.closeSubMenu(); 3260 } 3261 } 3262 function _handlePopupDestroy() { 3263 this.emit('onDestroy'); 3264 for (let i = 0; i < this.menuItems.length; i++) { 3265 const item = this.menuItems[i]; 3266 item.blur(); 3267 item.destroySubMenu(); 3268 } 3269 } 3270 function _handleAutoHide(event) { 3271 return !this.containsTarget(event.target); 3272 } 3273 function _handleItemFocus(event) { 3274 const { 3275 item 3276 } = event.getData(); 3277 if (_classPrivateFieldGet(_focusedItem, this) === item) { 3278 return; 3279 } 3280 this.clearFocus(); 3281 _classPrivateFieldSet(_focusedItem, this, item); 3282 } 3283 function _handleItemBlur() { 3284 this.clearFocus(); 3285 } 3286 3287 class MenuManager { 3288 /** 3289 * @private 3290 */ 3291 static Data = {}; 3292 3293 /** 3294 * @private 3295 */ 3296 static currentItem = null; 3297 constructor() { 3298 throw new Error('You cannot make an instance of MenuManager.'); 3299 } 3300 static show(...args) { 3301 if (this.currentItem !== null) { 3302 this.currentItem.popupWindow.close(); 3303 } 3304 this.currentItem = this.create.apply(this, args); 3305 this.currentItem.popupWindow.show(); 3306 } 3307 static create(options) { 3308 let menuId = null; 3309 3310 // Compatibility 3311 const bindElement = arguments[1]; 3312 const menuItems = arguments[2]; 3313 const params = arguments[3]; 3314 if (main_core.Type.isPlainObject(options) && !bindElement && !menuItems && !params) { 3315 menuId = options.id; 3316 if (!main_core.Type.isStringFilled(menuId)) { 3317 throw new Error('BX.Main.Menu.create: "id" parameter is required.'); 3318 } 3319 } else { 3320 menuId = options; 3321 } 3322 if (!this.Data[menuId]) { 3323 const menu = new Menu(options, bindElement, menuItems, params); 3324 menu.getPopupWindow().subscribe('onDestroy', () => { 3325 MenuManager.destroy(menuId); 3326 }); 3327 this.Data[menuId] = menu; 3328 } 3329 return this.Data[menuId]; 3330 } 3331 static getCurrentMenu() { 3332 return this.currentItem; 3333 } 3334 static getMenuById(id) { 3335 return this.Data[id] ? this.Data[id] : null; 3336 } 3337 3338 /** 3339 * compatibility 3340 * @private 3341 */ 3342 static onPopupDestroy(popupMenuWindow) { 3343 this.destroy(popupMenuWindow.id); 3344 } 3345 static destroy(id) { 3346 const menu = this.getMenuById(id); 3347 if (menu) { 3348 if (this.currentItem === menu) { 3349 this.currentItem = null; 3350 } 3351 delete this.Data[id]; 3352 menu.getPopupWindow().destroy(); 3353 } 3354 } 3355 } 3356 3357 class PopupManager { 3358 static _popups = []; 3359 static _currentPopup = null; 3360 constructor() { 3361 throw new Error('You cannot make an instance of PopupManager.'); 3362 } 3363 static create(options) { 3364 let [popupId, bindElement, params] = arguments; // compatible arguments 3365 3366 let id = popupId; 3367 let compatMode = true; 3368 if (main_core.Type.isPlainObject(popupId) && !bindElement && !params) { 3369 compatMode = false;
3370 id = popupId.id; 3371 if (!main_core.Type.isStringFilled(id)) { 3372 throw new Error('BX.Main.Popup.Manager: "id" parameter is required.'); 3373 } 3374 } 3375 let popupWindow = this.getPopupById(id); 3376 if (popupWindow === null) { 3377 popupWindow = compatMode ? new Popup(popupId, bindElement, params) : new Popup(options); 3378 popupWindow.subscribe('onShow', this.handlePopupShow); 3379 popupWindow.subscribe('onClose', this.handlePopupClose); 3380 } 3381 return popupWindow; 3382 } 3383 3384 /** 3385 * @private 3386 */ 3387 static handleOnAfterInit(event) { 3388 event.getTarget().subscribeOnce('onDestroy', this.handlePopupDestroy); 3389 this._popups.forEach(popup => { 3390 if (popup.getId() === event.getTarget().getId()) { 3391 console.error(`Duplicate id (${popup.getId()}) for the BX.Main.Popup instance.`); 3392 } 3393 }); 3394 this._popups.push(event.getTarget()); 3395 } 3396 3397 /** 3398 * @private 3399 */ 3400 static handlePopupDestroy(event) { 3401 this._popups = this._popups.filter(popup => { 3402 return popup !== event.getTarget(); 3403 }); 3404 } 3405 3406 /** 3407 * @private 3408 */ 3409 static handlePopupShow(event) { 3410 if (this._currentPopup !== null) { 3411 this._currentPopup.close(); 3412 } 3413 this._currentPopup = event.getTarget(); 3414 } 3415 3416 /** 3417 * @private 3418 */ 3419 static handlePopupClose() { 3420 this._currentPopup = null; 3421 } 3422 static getCurrentPopup() { 3423 return this._currentPopup; 3424 } 3425 static isPopupExists(id) { 3426 return this.getPopupById(id) !== null; 3427 } 3428 static isAnyPopupShown() { 3429 for (let i = 0, length = this._popups.length; i < length; i++) { 3430 if (this._popups[i].isShown()) { 3431 return true; 3432 } 3433 } 3434 return false; 3435 } 3436 static getPopupById(id) { 3437 for (let i = 0; i < this._popups.length; i++) { 3438 if (this._popups[i].getId() === id) { 3439 return this._popups[i]; 3440 } 3441 } 3442 return null; 3443 } 3444 static getMaxZIndex() { 3445 let zIndex = 0; 3446 this.getPopups().forEach(popup => { 3447 zIndex = Math.max(zIndex, popup.getZindex()); 3448 }); 3449 return zIndex; 3450 } 3451 static getPopups() { 3452 return this._popups; 3453 } 3454 } 3455 PopupManager.handlePopupDestroy = PopupManager.handlePopupDestroy.bind(PopupManager); 3456 PopupManager.handlePopupShow = PopupManager.handlePopupShow.bind(PopupManager); 3457 PopupManager.handlePopupClose = PopupManager.handlePopupClose.bind(PopupManager); 3458 PopupManager.handleOnAfterInit = PopupManager.handleOnAfterInit.bind(PopupManager); 3459 main_core_events.EventEmitter.subscribe('BX.Main.Popup:onAfterInit', PopupManager.handleOnAfterInit); 3460 3461 /** 3462 * @deprecated use BX.UI.Button 3463 */ 3464 class ButtonLink extends Button { 3465 constructor(params) { 3466 super(params); 3467 this.buttonNode = main_core.Dom.create('button', { 3468 props: { 3469 className: 'popup-window-button popup-window-button-link' + (this.className.length > 0 ? ` ${this.className}` : ''), 3470 id: this.id 3471 }, 3472 attrs: { 3473 tabindex: '0', 3474 type: 'button' 3475 }, 3476 text: this.text, 3477 events: this.contextEvents 3478 }); 3479 } 3480 } 3481 3482 /** 3483 * @deprecated use BX.UI.Button 3484 */ 3485 class CustomButton extends Button { 3486 constructor(params) { 3487 super(params); 3488 this.buttonNode = main_core.Dom.create('span', { 3489 props: { 3490 className: this.className.length > 0 ? this.className : '', 3491 id: this.id 3492 }, 3493 events: this.contextEvents, 3494 text: this.text 3495 }); 3496 } 3497 } 3498 3499 /** 3500 * @deprecated 3501 */ 3502 class InputPopup { 3503 constructor(params) { 3504 this.id = params.id || 'bx-inp-popup-' + Math.round(Math.random() * 1000000); 3505 this.handler = params.handler || false; 3506 this.values = params.values || false; 3507 this.pInput = params.input; 3508 this.bValues = !!this.values; 3509 this.defaultValue = params.defaultValue || ''; 3510 this.openTitle = params.openTitle || ''; 3511 this.className = params.className || ''; 3512 this.noMRclassName = params.noMRclassName || 'ec-no-rm'; 3513 this.emptyClassName = params.noMRclassName || 'ec-label'; 3514 const _this = this; 3515 this.curInd = false; 3516 if (this.bValues) { 3517 this.pInput.onfocus = this.pInput.onclick = function (e) { 3518 if (this.value == _this.defaultValue) { 3519 this.value = ''; 3520 this.className = _this.className; 3521 } 3522 _this.ShowPopup(); 3523 return e.preventDefault(); 3524 }; 3525 this.pInput.onblur = function () { 3526 if (_this.bShowed) { 3527 setTimeout(function () { 3528 _this.ClosePopup(true); 3529 }, 200); 3530 } 3531 _this.OnChange(); 3532 }; 3533 } else { 3534 this.pInput.className = this.noMRclassName; 3535 this.pInput.onblur = this.OnChange.bind(this); 3536 } 3537 } 3538 ShowPopup() { 3539 if (this.bShowed) { 3540 return; 3541 } 3542 const _this = this; 3543 if (!this.oPopup) { 3544 const pWnd = main_core.Dom.create('DIV', { 3545 props: { 3546 className: 'bxecpl-loc-popup ' + this.className 3547 } 3548 }); 3549 for (let i = 0, l = this.values.length; i < l; i++) { 3550 const pRow = pWnd.appendChild(main_core.Dom.create('DIV', { 3551 props: { 3552 id: 'bxecmr_' + i 3553 }, 3554 text: this.values[i].NAME, 3555 events: { 3556 mouseover: function () { 3557 main_core.Dom.addClass(this, 'bxecplloc-over'); 3558 }, 3559 mouseout: function () { 3560 main_core.Dom.removeClass(this, 'bxecplloc-over'); 3561 }, 3562 click: function () { 3563 const ind = this.id.substr('bxecmr_'.length); 3564 _this.pInput.value = _this.values[ind].NAME; 3565 _this.curInd = ind; 3566 _this.OnChange(); 3567 _this.ClosePopup(true); 3568 } 3569 } 3570 })); 3571 if (this.values[i].DESCRIPTION) { 3572 pRow.title = this.values[i].DESCRIPTION; 3573 } 3574 if (this.values[i].CLASS_NAME) { 3575 main_core.Dom.addClass(pRow, this.values[i].CLASS_NAME); 3576 } 3577 if (this.values[i].URL) { 3578 pRow.appendChild(main_core.Dom.create('a', { 3579 props: { 3580 href: this.values[i].URL, 3581 className: 'bxecplloc-view', 3582 target: '_blank', 3583 title: this.openTitle 3584 } 3585 })); 3586 } 3587 } 3588 this.oPopup = new Popup(this.id, this.pInput, { 3589 autoHide: true, 3590 offsetTop: 1, 3591 offsetLeft: 0, 3592 lightShadow: true, 3593 closeByEsc: true, 3594 content: pWnd, 3595 events: { 3596 onClose: this.ClosePopup.bind(this) 3597 } 3598 }); 3599 } 3600 this.oPopup.show(); 3601 this.pInput.select(); 3602 this.bShowed = true;
3603 main_core_events.EventEmitter.emit(this, 'onInputPopupShow', new main_core_events.BaseEvent({ 3604 compatData: [this] 3605 })); 3606 } 3607 ClosePopup(bClosePopup) { 3608 this.bShowed = false; 3609 if (this.pInput.value === '') { 3610 this.OnChange(); 3611 } 3612 main_core_events.EventEmitter.emit(this, 'onInputPopupClose', new main_core_events.BaseEvent({ 3613 compatData: [this] 3614 })); 3615 if (bClosePopup === true) { 3616 this.oPopup.close(); 3617 } 3618 } 3619 OnChange() { 3620 let val = this.pInput.value; 3621 if (this.bValues) { 3622 if (this.pInput.value == '' || this.pInput.value == this.defaultValue) { 3623 this.pInput.value = this.defaultValue; 3624 this.pInput.className = this.emptyClassName; 3625 val = ''; 3626 } else { 3627 this.pInput.className = ''; 3628 } 3629 } 3630 if (isNaN(parseInt(this.curInd)) || this.curInd !== false && val != this.values[this.curInd].NAME) { 3631 this.curInd = false; 3632 } else { 3633 this.curInd = parseInt(this.curInd); 3634 } 3635 main_core_events.EventEmitter.emit(this, 'onInputPopupChanged', new main_core_events.BaseEvent({ 3636 compatData: [this, this.curInd, val] 3637 })); 3638 if (this.handler && typeof this.handler == 'function') { 3639 this.handler({ 3640 ind: this.curInd, 3641 value: val 3642 }); 3643 } 3644 } 3645 Set(ind, val, bOnChange) { 3646 this.curInd = ind; 3647 if (this.curInd !== false) { 3648 this.pInput.value = this.values[this.curInd].NAME; 3649 } else { 3650 this.pInput.value = val; 3651 } 3652 if (bOnChange !== false) { 3653 this.OnChange(); 3654 } 3655 } 3656 Get(ind) { 3657 let id = false; 3658 if (typeof ind == 'undefined') { 3659 ind = this.curInd; 3660 } 3661 if (ind !== false && this.values[ind]) { 3662 id = this.values[ind].ID; 3663 } 3664 return id; 3665 } 3666 GetIndex(id) { 3667 for (let i = 0, l = this.values.length; i < l; i++) { 3668 if (this.values[i].ID == id) { 3669 return i; 3670 } 3671 } 3672 return false; 3673 } 3674 Deactivate(bDeactivate) { 3675 if (this.pInput.value == '' || this.pInput.value == this.defaultValue) { 3676 if (bDeactivate) { 3677 this.pInput.value = ''; 3678 this.pInput.className = this.noMRclassName; 3679 } else if (this.oEC.bUseMR) { 3680 this.pInput.value = this.defaultValue; 3681 this.pInput.className = this.emptyClassName; 3682 } 3683 } 3684 this.pInput.disabled = bDeactivate; 3685 } 3686 } 3687 3688 /** 3689 * @deprecated use Menu.Item class instead: import { MenuItem } from 'main.popup' 3690 */ 3691 class PopupMenuItem extends MenuItem { 3692 // No additional functionality, just for compatibility 3693 } 3694 3695 /** 3696 * @deprecated use Menu class instead: import { Menu } from 'main.popup' 3697 */ 3698 class PopupMenuWindow extends Menu { 3699 // No additional functionality, just for compatibility 3700 } 3701 3702 /** 3703 * @deprecated use Popup class instead: import { Popup } from 'main.popup' 3704 */ 3705 class PopupWindow extends Popup { 3706 // No additional functionality, just for compatibility 3707 } 3708 3709 /** 3710 * @deprecated use BX.UI.Button 3711 */ 3712 class PopupWindowButton extends Button { 3713 // No additional functionality, just for compatibility 3714 } 3715 3716 /** 3717 * @deprecated use BX.UI.Button 3718 */ 3719 class PopupWindowButtonLink extends ButtonLink { 3720 // No additional functionality, just for compatibility 3721 } 3722 3723 /** 3724 * @deprecated use BX.UI.Button 3725 */ 3726 class PopupWindowCustomButton extends CustomButton { 3727 // No additional functionality, just for compatibility 3728 } 3729 3730 /* 3731 3732 //ES6 3733 import { Popup, PopupManager, CloseIconSize } from 'main.popup'; 3734 const popup = new Popup(); 3735 PopupManager.create(); 3736 3737 //ES5 3738 var popup = new BX.Main.Popup(); 3739 BX.Main.PopupManager.create(); 3740 BX.Main.Popup.CloseIconSize; 3741 3742 //ES6 3743 import { Menu, MenuItem, MenuManager } from 'main.popup'; 3744 const menu = new Menu(); 3745 const item = new MenuItem(); 3746 MenuManager.create(); 3747 3748 //ES5 3749 var menu = new BX.Main.Menu(); 3750 var item = new BX.Main.MenuItem(); 3751 BX.Main.MenuManager.create(); 3752 3753 */ 3754 3755 const BX = main_core.Reflection.namespace('BX'); 3756 3757 /** @deprecated use BX.Main.Popup or import { Popup } from 'main.popup' */ 3758 BX.PopupWindow = Popup; 3759 3760 /** @deprecated use BX.Main.PopupManager or import { PopupManager } from 'main.popup' */ 3761 BX.PopupWindowManager = PopupManager; 3762 3763 /** @deprecated use BX.Main.Menu or import { Menu } from 'main.popup' */ 3764 BX.PopupMenuWindow = Menu; 3765 3766 /** @deprecated use BX.Main.MenuManager or import { MenuManager } from 'main.popup' */ 3767 BX.PopupMenu = MenuManager; 3768 3769 /** @deprecated use BX.Main.MenuItem or import { MenuItem } from 'main.popup' */ 3770 BX.PopupMenuItem = MenuItem; 3771 3772 /** @deprecated use BX.UI.Button */ 3773 BX.PopupWindowButton = Button; 3774 3775 /** @deprecated use BX.UI.Button */ 3776 BX.PopupWindowButtonLink = ButtonLink; 3777 3778 /** @deprecated use BX.UI.Button */ 3779 BX.PopupWindowCustomButton = CustomButton; 3780 3781 /** @deprecated use another API */
3782 window.BXInputPopup = InputPopup; 3783 3784 exports.CloseIconSize = CloseIconSize; 3785 exports.Menu = Menu; 3786 exports.MenuItem = MenuItem; 3787 exports.MenuManager = MenuManager; 3788 exports.Popup = Popup; 3789 exports.PopupManager = PopupManager; 3790 exports.PopupMenu = MenuManager; 3791 exports.PopupMenuItem = PopupMenuItem; 3792 exports.PopupMenuWindow = PopupMenuWindow; 3793 exports.PopupWindow = PopupWindow; 3794 exports.PopupWindowButton = PopupWindowButton; 3795 exports.PopupWindowButtonLink = PopupWindowButtonLink; 3796 exports.PopupWindowCustomButton = PopupWindowCustomButton; 3797 exports.PopupWindowManager = PopupManager; 3798 3799})(this.BX.Main = this.BX.Main || {}, BX, BX, BX, BX.Event, BX.UI.Accessibility, BX); 3800//# sourceMappingURL=main.popup.bundle.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.