1// Copyright (c) 2021-2025 GrayBits LLC 2 3import * as InitializerCallbacks from 'gray_matter/modules/initializable/initializer_callbacks' 4import * as Notification from 'gray_matter/utility/notification' 5import * as Builder from 'gray_matter/utility/builder' 6import Tabs from 'gray_matter/interfaces/tabs' 7import axios from 'axios' 8 9export default class PopInInterface{ 10 constructor(parent, options = {}){ 11 if (options.url && options.content){ 12 throw 'Specify either a url or content'; 13 } 14 this.parent = parent; 15 this.url = options.url; 16 this.content = options.content; 17 this.wrapper = options.wrapper; 18 if (options.setup){ 19 this.setup = options.setup; 20 } 21 this.createInterface(options); 22 } 23 async createInterface(options){ 24 try{ 25 let interface_html; 26 if (this.url){ 27 let method = options.method || 'get'; 28 let params = options.params || {}; 29 if (method == 'get'){ 30 this.response = await axios.get(this.url, { params: params }); 31 } else { 32 this.response = await axios[method](this.url, params); 33 } 34 this.content = this.response.data.interface; 35 } 36 let parent_popin = this.parent.closest('.pop_in'); 37 if (!options.preserve_popins){ 38 document.querySelectorAll('.pop_in').forEach((e) => { 39 if (parent_popin != e){ 40 e.remove(); 41 e.interface.parent.classList.remove('selected'); 42 } 43 }); 44 } 45 this.parent.classList.add('selected'); 46 if (this.wrapper){ 47 let wrapper = document.createElement('div') 48 wrapper.className = this.wrapper + " pop_in prepop simple_pop"; 49 wrapper.innerHTML = this.content; 50 this.parent.appendChild(wrapper); 51 this.element = wrapper; 52 } else { 53 this.element = Builder.createFromHTML(this.content); 54 this.parent.append(this.element); 55 } 56 this.parent.offsetHeight; 57 this.element.classList.remove('prepop'); 58 this.element.interface = this; 59 this.element.querySelectorAll('.cancel_popin').forEach((c) => c.addEventListener('click', e => this.cancel(e))); 60 if (options.position){ 61 if (options.position.right){ 62 this.element.style.right = options.position.right + 'px'; 63 } 64 if (options.position.left){ 65 this.element.style.left = options.position.left + 'px'; 66 } 67 if (options.position.top){ 68 this.element.style.top = options.position.top + 'px'; 69 } 70 if (options.position.bottom){ 71 this.element.style.bottom = options.position.bottom + 'px'; 72 } 73 } 74 InitializerCallbacks.applyAll(this.element); 75 Tabs.init(this.element); 76 // Call at the end after all interfaces have initialized 77 if (this.setup){ 78 this.setup(this); 79 } 80 } catch(error){ 81 if (this.response){ 82 Notification.showResponseError(error); 83 } else { 84 Notification.showError(error); 85 } 86 } 87 } 88 cancel(e, parent_content = false){ 89 this.element.addEventListener('transitionend', (e) => this.destroy(e, parent_content)); 90 this.element.offsetHeight; 91 this.element.classList.add('prepop'); 92 this.parent.classList.remove('selected'); 93 this.parent.dispatchEvent(new CustomEvent('cancelpopin', { detail: this, bubbles: true })); 94 } 95 destroy(e, parent_content){ 96 if (e.propertyName == 'opacity'){ 97 this.element.remove(); 98 if (parent_content){ 99 this.parent.innerHTML = parent_content; 100 } 101 } 102 } 103};
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.