1(function($){ 2 'use strict'; 3 4 class PopupModal { 5 constructor() { 6 if (window.keydesignPopupModalInit) return; 7 window.keydesignPopupModalInit = true; 8 this.isOpen = false; 9 this.currentPopupId = null; 10 this.currentPopupContainer = null; 11 this.currentContentOffcanvas = null; 12 this.init(); 13 } 14 15 init() { 16 this.bindEvents(); 17 } 18 19 bindEvents() { 20 $(document) 21 .off('click.kdpm keydown.kdpm') 22 .on('click.kdpm', 'a[href*="#modal"],a[href*="#keydesign-content-offcanvas-"]', (e) => { 23 const $t = $(e.currentTarget); 24 const href = $t.attr('href') || ''; 25 if (!href.startsWith('#')) return; 26 e.preventDefault(); 27 if (href.startsWith('#keydesign-content-offcanvas-')) { 28 this.handleKeyDesignOffCanvasWithContent(href); 29 return; 30 } 31 if (href.startsWith('#modal-search-') || href.startsWith('#modal-team-')) { 32 this.handleKeyDesignModalWithContent(href); 33 return; 34 } 35 const id = this.extractPopupId(href); 36 if (id) this.openModal(id); 37 }) 38 .on('keydown.kdpm', (e) => { 39 if (e.key === 'Escape' && this.isOpen) this.closeModal(); 40 }); 41 42 $(document).off('click.kdpm-overlay').on('click.kdpm-overlay', '.keydesign-popup-overlay', () => this.closeModal()); 43 $(document).off('click.kdpm-content').on('click.kdpm-content', '.keydesign-popup-content', (e) => e.stopPropagation()); 44 } 45 46 extractPopupId(href) { 47 const m = href.match(/#modal-(\d+)/); 48 return m ? parseInt(m[1], 10) : null; 49 } 50 51 openModal(popupId = null) { 52 if (this.isOpen) this.closeModal(); 53 54 if (!popupId) { 55 console.error('Popup ID is required'); 56 return; 57 } 58 59 const $popupContainer = $(`.keydesign-popup-modal[data-popup-id="${popupId}"], .keydesign-popup-offcanvas[data-popup-id="${popupId}"]`); 60 61 if (!$popupContainer.length) { 62 console.error('Popup not found:', popupId); 63 return; 64 } 65 66 const $overlay = $('.keydesign-popup-overlay'); 67 if (!$overlay.length) { 68 console.error('Popup overlay not found'); 69 return; 70 } 71 72 this.isOpen = true; 73 this.currentPopupId = popupId; 74 this.currentPopupContainer = $popupContainer; 75 76 $overlay.addClass('active'); 77 $popupContainer.addClass('active'); 78 $('body').addClass('keydesign-popup-open'); 79 } 80 81 closeModal() { 82 if (!this.isOpen) return; 83 this.isOpen = false; 84 85 if (this.currentContentOffcanvas) { 86 this.closeContentOffcanvas(this.currentContentOffcanvas); 87 } 88 89 const $overlay = $('.keydesign-popup-overlay'); 90 if ($overlay.length) { 91 $overlay.removeClass('active'); 92 } 93 94 if (this.currentPopupContainer && this.currentPopupContainer.length) { 95 this.currentPopupContainer.removeClass('active'); 96 97 if (this.currentPopupContainer.data('special-modal')) { 98 setTimeout(() => { 99 if (this.currentPopupContainer && !this.currentPopupContainer.hasClass('active')) { 100 this.currentPopupContainer.remove(); 101 } 102 }, 300); 103 } 104 } 105 106 this.currentPopupId = null; 107 this.currentPopupContainer = null; 108 109 $('body').removeClass('keydesign-popup-open'); 110 } 111 112 handleKeyDesignModalWithContent(href) { 113 const modalId = href.substring(1); 114 const $src = $('#' + modalId); 115 if (!$src.length) return; 116 117 const clone = $src.clone(); 118 clone.removeAttr('id'); 119 120 const $overlay = $('.keydesign-popup-overlay'); 121 if (!$overlay.length) { 122 console.error('Popup overlay not found'); 123 return; 124 } 125 126 let $modal = $('.keydesign-popup-modal[data-special-modal="' + modalId + '"]'); 127 if (!$modal.length) {
128 $modal = $('<div class="keydesign-popup-modal" data-special-modal="' + modalId + '"><div class="keydesign-popup-content"></div></div>'); 129 $('body').append($modal); 130 } 131 132 this.isOpen = true; 133 this.currentPopupId = modalId; 134 this.currentPopupContainer = $modal; 135 136 if (href.startsWith('#modal-search-')) { 137 $modal.addClass('keydesign-search-modal'); 138 } else if (href.startsWith('#modal-team-')) { 139 $modal.addClass('keydesign-team-modal'); 140 } 141 142 $modal.find('.keydesign-popup-content').html(clone); 143 $overlay.addClass('active'); 144 $modal.addClass('active'); 145 $('body').addClass('keydesign-popup-open'); 146 147 const $tr = $('a[href="' + href + '"]'); 148 if ($tr.length) $tr.attr('aria-expanded', 'true'); 149 } 150 151 handleKeyDesignOffCanvasWithContent(href) { 152 const id = href.substring(1); 153 const $uc = $('#' + id); 154 if (!$uc.length) return; 155 156 if (!$uc.data('events-bound')) { 157 $uc.find('.keydesign-content-overlay').on('click', () => this.closeContentOffcanvas($uc)); 158 $(document).on('keydown.contentOffcanvas', (e) => { 159 if (e.keyCode === 27 && $uc.hasClass('active')) this.closeContentOffcanvas($uc); 160 }); 161 $uc.data('events-bound', true); 162 } 163 164 this.isOpen = true; 165 this.currentPopupId = id; 166 this.currentContentOffcanvas = $uc; 167 168 $uc.addClass('active'); 169 $('body').addClass('keydesign-content-offcanvas-open'); 170 171 const $tr = $('a[href="' + href + '"]'); 172 if ($tr.length) $tr.attr('aria-expanded', 'true'); 173 } 174 175 closeContentOffcanvas($oc) { 176 if (!$oc || !$oc.hasClass('active')) return; 177 $oc.removeClass('active'); 178 $('body').removeClass('keydesign-content-offcanvas-open'); 179 const $tr = $('a[href="#' + (this.currentPopupId || '') + '"]'); 180 if ($tr.length) $tr.attr('aria-expanded', 'false'); 181 this.isOpen = false; 182 this.currentPopupId = null; 183 this.currentContentOffcanvas = null; 184 } 185 } 186 187 $(function () { 188 window.keydesignPopupModal = new PopupModal(); 189 }); 190 })(jQuery);
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.