mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-21 10:55:13 +00:00
Refactor code for consistency and readability
- Standardized string quotes to double quotes across multiple files. - Improved formatting and indentation for better readability. - Added a function to format multiline text in tools rendering. - Enhanced dropdown and action button handlers for better event management. - Updated the theme application logic to initialize on page load. - Refactored utility functions for consistency and clarity. - Improved error handling and user feedback in download and share functionalities.
This commit is contained in:
@@ -2,7 +2,18 @@
|
||||
* Modal functionality for file viewing
|
||||
*/
|
||||
|
||||
import { fetchFileContent, fetchData, getVSCodeInstallUrl, copyToClipboard, showToast, downloadFile, shareFile, getResourceType, escapeHtml, getResourceIcon } from './utils';
|
||||
import {
|
||||
fetchFileContent,
|
||||
fetchData,
|
||||
getVSCodeInstallUrl,
|
||||
copyToClipboard,
|
||||
showToast,
|
||||
downloadFile,
|
||||
shareFile,
|
||||
getResourceType,
|
||||
escapeHtml,
|
||||
getResourceIcon,
|
||||
} from "./utils";
|
||||
|
||||
// Modal state
|
||||
let currentFilePath: string | null = null;
|
||||
@@ -37,29 +48,30 @@ let collectionsCache: CollectionsData | null = null;
|
||||
*/
|
||||
function getFocusableElements(container: HTMLElement): HTMLElement[] {
|
||||
const focusableSelectors = [
|
||||
'button:not([disabled])',
|
||||
'a[href]',
|
||||
'input:not([disabled])',
|
||||
'select:not([disabled])',
|
||||
'textarea:not([disabled])',
|
||||
'[tabindex]:not([tabindex="-1"])'
|
||||
].join(', ');
|
||||
|
||||
return Array.from(container.querySelectorAll<HTMLElement>(focusableSelectors))
|
||||
.filter(el => el.offsetParent !== null); // Filter out hidden elements
|
||||
"button:not([disabled])",
|
||||
"a[href]",
|
||||
"input:not([disabled])",
|
||||
"select:not([disabled])",
|
||||
"textarea:not([disabled])",
|
||||
'[tabindex]:not([tabindex="-1"])',
|
||||
].join(", ");
|
||||
|
||||
return Array.from(
|
||||
container.querySelectorAll<HTMLElement>(focusableSelectors)
|
||||
).filter((el) => el.offsetParent !== null); // Filter out hidden elements
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle keyboard navigation within modal (focus trap)
|
||||
*/
|
||||
function handleModalKeydown(e: KeyboardEvent, modal: HTMLElement): void {
|
||||
if (e.key === 'Tab') {
|
||||
if (e.key === "Tab") {
|
||||
const focusableElements = getFocusableElements(modal);
|
||||
if (focusableElements.length === 0) return;
|
||||
|
||||
|
||||
const firstElement = focusableElements[0];
|
||||
const lastElement = focusableElements[focusableElements.length - 1];
|
||||
|
||||
|
||||
if (e.shiftKey) {
|
||||
// Shift+Tab: if on first element, wrap to last
|
||||
if (document.activeElement === firstElement) {
|
||||
@@ -80,23 +92,23 @@ function handleModalKeydown(e: KeyboardEvent, modal: HTMLElement): void {
|
||||
* Setup modal functionality
|
||||
*/
|
||||
export function setupModal(): void {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const closeBtn = document.getElementById('close-modal');
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
const downloadBtn = document.getElementById('download-btn');
|
||||
const shareBtn = document.getElementById('share-btn');
|
||||
const modal = document.getElementById("file-modal");
|
||||
const closeBtn = document.getElementById("close-modal");
|
||||
const copyBtn = document.getElementById("copy-btn");
|
||||
const downloadBtn = document.getElementById("download-btn");
|
||||
const shareBtn = document.getElementById("share-btn");
|
||||
|
||||
if (!modal) return;
|
||||
|
||||
closeBtn?.addEventListener('click', closeModal);
|
||||
|
||||
modal.addEventListener('click', (e) => {
|
||||
closeBtn?.addEventListener("click", closeModal);
|
||||
|
||||
modal.addEventListener("click", (e) => {
|
||||
if (e.target === modal) closeModal();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (!modal.classList.contains('hidden')) {
|
||||
if (e.key === 'Escape') {
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (!modal.classList.contains("hidden")) {
|
||||
if (e.key === "Escape") {
|
||||
closeModal();
|
||||
} else {
|
||||
handleModalKeydown(e, modal);
|
||||
@@ -104,32 +116,41 @@ export function setupModal(): void {
|
||||
}
|
||||
});
|
||||
|
||||
copyBtn?.addEventListener('click', async () => {
|
||||
copyBtn?.addEventListener("click", async () => {
|
||||
if (currentFileContent) {
|
||||
const success = await copyToClipboard(currentFileContent);
|
||||
showToast(success ? 'Copied to clipboard!' : 'Failed to copy', success ? 'success' : 'error');
|
||||
showToast(
|
||||
success ? "Copied to clipboard!" : "Failed to copy",
|
||||
success ? "success" : "error"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
downloadBtn?.addEventListener('click', async () => {
|
||||
downloadBtn?.addEventListener("click", async () => {
|
||||
if (currentFilePath) {
|
||||
const success = await downloadFile(currentFilePath);
|
||||
showToast(success ? 'Download started!' : 'Download failed', success ? 'success' : 'error');
|
||||
showToast(
|
||||
success ? "Download started!" : "Download failed",
|
||||
success ? "success" : "error"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
shareBtn?.addEventListener('click', async () => {
|
||||
shareBtn?.addEventListener("click", async () => {
|
||||
if (currentFilePath) {
|
||||
const success = await shareFile(currentFilePath);
|
||||
showToast(success ? 'Link copied to clipboard!' : 'Failed to copy link', success ? 'success' : 'error');
|
||||
showToast(
|
||||
success ? "Link copied to clipboard!" : "Failed to copy link",
|
||||
success ? "success" : "error"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Setup install dropdown toggle
|
||||
setupInstallDropdown('install-dropdown');
|
||||
setupInstallDropdown("install-dropdown");
|
||||
|
||||
// Handle browser back/forward navigation
|
||||
window.addEventListener('hashchange', handleHashChange);
|
||||
window.addEventListener("hashchange", handleHashChange);
|
||||
|
||||
// Check for deep link on initial load
|
||||
handleHashChange();
|
||||
@@ -140,14 +161,14 @@ export function setupModal(): void {
|
||||
*/
|
||||
function handleHashChange(): void {
|
||||
const hash = window.location.hash;
|
||||
|
||||
if (hash && hash.startsWith('#file=')) {
|
||||
|
||||
if (hash && hash.startsWith("#file=")) {
|
||||
const filePath = decodeURIComponent(hash.slice(6));
|
||||
if (filePath && filePath !== currentFilePath) {
|
||||
const type = getResourceType(filePath);
|
||||
openFileModal(filePath, type, false); // Don't update hash since we're responding to it
|
||||
}
|
||||
} else if (!hash || hash === '#') {
|
||||
} else if (!hash || hash === "#") {
|
||||
// No hash or empty hash - close modal if open
|
||||
if (currentFilePath) {
|
||||
closeModal(false); // Don't update hash since we're responding to it
|
||||
@@ -162,11 +183,15 @@ function updateHash(filePath: string | null): void {
|
||||
if (filePath) {
|
||||
const newHash = `#file=${encodeURIComponent(filePath)}`;
|
||||
if (window.location.hash !== newHash) {
|
||||
history.pushState(null, '', newHash);
|
||||
history.pushState(null, "", newHash);
|
||||
}
|
||||
} else {
|
||||
if (window.location.hash) {
|
||||
history.pushState(null, '', window.location.pathname + window.location.search);
|
||||
history.pushState(
|
||||
null,
|
||||
"",
|
||||
window.location.pathname + window.location.search
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,16 +203,19 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
const container = document.getElementById(containerId);
|
||||
if (!container) return;
|
||||
|
||||
const toggle = container.querySelector<HTMLButtonElement>('.install-btn-toggle');
|
||||
const menu = container.querySelector('.install-dropdown-menu');
|
||||
const menuItems = container.querySelectorAll<HTMLAnchorElement>('.install-dropdown-menu a');
|
||||
|
||||
toggle?.addEventListener('click', (e) => {
|
||||
const toggle = container.querySelector<HTMLButtonElement>(
|
||||
".install-btn-toggle"
|
||||
);
|
||||
const menuItems = container.querySelectorAll<HTMLAnchorElement>(
|
||||
".install-dropdown-menu a"
|
||||
);
|
||||
|
||||
toggle?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const isOpen = container.classList.toggle('open');
|
||||
toggle.setAttribute('aria-expanded', String(isOpen));
|
||||
|
||||
const isOpen = container.classList.toggle("open");
|
||||
toggle.setAttribute("aria-expanded", String(isOpen));
|
||||
|
||||
// Focus first menu item when opening
|
||||
if (isOpen && menuItems.length > 0) {
|
||||
menuItems[0].focus();
|
||||
@@ -195,11 +223,11 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
});
|
||||
|
||||
// Keyboard navigation for dropdown
|
||||
toggle?.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {
|
||||
toggle?.addEventListener("keydown", (e) => {
|
||||
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
container.classList.add('open');
|
||||
toggle.setAttribute('aria-expanded', 'true');
|
||||
container.classList.add("open");
|
||||
toggle.setAttribute("aria-expanded", "true");
|
||||
if (menuItems.length > 0) {
|
||||
menuItems[0].focus();
|
||||
}
|
||||
@@ -208,15 +236,15 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
|
||||
// Keyboard navigation within menu
|
||||
menuItems.forEach((item, index) => {
|
||||
item.addEventListener('keydown', (e) => {
|
||||
item.addEventListener("keydown", (e) => {
|
||||
switch (e.key) {
|
||||
case 'ArrowDown':
|
||||
case "ArrowDown":
|
||||
e.preventDefault();
|
||||
if (index < menuItems.length - 1) {
|
||||
menuItems[index + 1].focus();
|
||||
}
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
if (index > 0) {
|
||||
menuItems[index - 1].focus();
|
||||
@@ -224,34 +252,34 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
toggle?.focus();
|
||||
}
|
||||
break;
|
||||
case 'Escape':
|
||||
case "Escape":
|
||||
e.preventDefault();
|
||||
container.classList.remove('open');
|
||||
toggle?.setAttribute('aria-expanded', 'false');
|
||||
container.classList.remove("open");
|
||||
toggle?.setAttribute("aria-expanded", "false");
|
||||
toggle?.focus();
|
||||
break;
|
||||
case 'Tab':
|
||||
case "Tab":
|
||||
// Close menu on tab out
|
||||
container.classList.remove('open');
|
||||
toggle?.setAttribute('aria-expanded', 'false');
|
||||
container.classList.remove("open");
|
||||
toggle?.setAttribute("aria-expanded", "false");
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!container.contains(e.target as Node)) {
|
||||
container.classList.remove('open');
|
||||
toggle?.setAttribute('aria-expanded', 'false');
|
||||
container.classList.remove("open");
|
||||
toggle?.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
});
|
||||
|
||||
// Close dropdown when clicking a menu item
|
||||
container.querySelectorAll('.install-dropdown-menu a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
container.classList.remove('open');
|
||||
toggle?.setAttribute('aria-expanded', 'false');
|
||||
container.querySelectorAll(".install-dropdown-menu a").forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
container.classList.remove("open");
|
||||
toggle?.setAttribute("aria-expanded", "false");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -263,84 +291,103 @@ export function setupInstallDropdown(containerId: string): void {
|
||||
* @param updateUrl - Whether to update the URL hash (default: true)
|
||||
* @param trigger - The element that triggered the modal (for focus return)
|
||||
*/
|
||||
export async function openFileModal(filePath: string, type: string, updateUrl = true, trigger?: HTMLElement): Promise<void> {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const title = document.getElementById('modal-title');
|
||||
const modalContent = document.getElementById('modal-content');
|
||||
const contentEl = modalContent?.querySelector('code');
|
||||
const installDropdown = document.getElementById('install-dropdown');
|
||||
const installBtnMain = document.getElementById('install-btn-main') as HTMLAnchorElement | null;
|
||||
const installVscode = document.getElementById('install-vscode') as HTMLAnchorElement | null;
|
||||
const installInsiders = document.getElementById('install-insiders') as HTMLAnchorElement | null;
|
||||
const copyBtn = document.getElementById('copy-btn');
|
||||
const downloadBtn = document.getElementById('download-btn');
|
||||
const closeBtn = document.getElementById('close-modal');
|
||||
export async function openFileModal(
|
||||
filePath: string,
|
||||
type: string,
|
||||
updateUrl = true,
|
||||
trigger?: HTMLElement
|
||||
): Promise<void> {
|
||||
const modal = document.getElementById("file-modal");
|
||||
const title = document.getElementById("modal-title");
|
||||
const modalContent = document.getElementById("modal-content");
|
||||
const contentEl = modalContent?.querySelector("code");
|
||||
const installDropdown = document.getElementById("install-dropdown");
|
||||
const installBtnMain = document.getElementById(
|
||||
"install-btn-main"
|
||||
) as HTMLAnchorElement | null;
|
||||
const installVscode = document.getElementById(
|
||||
"install-vscode"
|
||||
) as HTMLAnchorElement | null;
|
||||
const installInsiders = document.getElementById(
|
||||
"install-insiders"
|
||||
) as HTMLAnchorElement | null;
|
||||
const copyBtn = document.getElementById("copy-btn");
|
||||
const downloadBtn = document.getElementById("download-btn");
|
||||
const closeBtn = document.getElementById("close-modal");
|
||||
|
||||
if (!modal || !title || !modalContent) return;
|
||||
|
||||
currentFilePath = filePath;
|
||||
currentFileType = type;
|
||||
|
||||
|
||||
// Track trigger element for focus return
|
||||
triggerElement = trigger || document.activeElement as HTMLElement;
|
||||
|
||||
triggerElement = trigger || (document.activeElement as HTMLElement);
|
||||
|
||||
// Update URL for deep linking
|
||||
if (updateUrl) {
|
||||
updateHash(filePath);
|
||||
}
|
||||
|
||||
|
||||
// Show modal with loading state
|
||||
title.textContent = filePath.split('/').pop() || filePath;
|
||||
modal.classList.remove('hidden');
|
||||
|
||||
title.textContent = filePath.split("/").pop() || filePath;
|
||||
modal.classList.remove("hidden");
|
||||
|
||||
// Set focus to close button for accessibility
|
||||
setTimeout(() => {
|
||||
closeBtn?.focus();
|
||||
}, 0);
|
||||
|
||||
// Handle collections differently - show as item list
|
||||
if (type === 'collection') {
|
||||
await openCollectionModal(filePath, title, modalContent, installDropdown, copyBtn, downloadBtn);
|
||||
if (type === "collection") {
|
||||
await openCollectionModal(
|
||||
filePath,
|
||||
title,
|
||||
modalContent,
|
||||
installDropdown,
|
||||
copyBtn,
|
||||
downloadBtn
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Regular file modal
|
||||
if (contentEl) {
|
||||
contentEl.textContent = 'Loading...';
|
||||
contentEl.textContent = "Loading...";
|
||||
}
|
||||
|
||||
|
||||
// Show copy/download buttons for regular files
|
||||
if (copyBtn) copyBtn.style.display = 'inline-flex';
|
||||
if (downloadBtn) downloadBtn.style.display = 'inline-flex';
|
||||
|
||||
if (copyBtn) copyBtn.style.display = "inline-flex";
|
||||
if (downloadBtn) downloadBtn.style.display = "inline-flex";
|
||||
|
||||
// Restore pre/code structure if it was replaced by collection view
|
||||
if (!modalContent.querySelector('pre')) {
|
||||
if (!modalContent.querySelector("pre")) {
|
||||
modalContent.innerHTML = '<pre id="modal-content"><code></code></pre>';
|
||||
}
|
||||
const codeEl = modalContent.querySelector('code');
|
||||
const codeEl = modalContent.querySelector("code");
|
||||
|
||||
// Setup install dropdown
|
||||
const vscodeUrl = getVSCodeInstallUrl(type, filePath, false);
|
||||
const insidersUrl = getVSCodeInstallUrl(type, filePath, true);
|
||||
|
||||
|
||||
if (vscodeUrl && installDropdown) {
|
||||
installDropdown.style.display = 'inline-flex';
|
||||
installDropdown.classList.remove('open');
|
||||
installDropdown.style.display = "inline-flex";
|
||||
installDropdown.classList.remove("open");
|
||||
if (installBtnMain) installBtnMain.href = vscodeUrl;
|
||||
if (installVscode) installVscode.href = vscodeUrl;
|
||||
if (installInsiders) installInsiders.href = insidersUrl || '#';
|
||||
if (installInsiders) installInsiders.href = insidersUrl || "#";
|
||||
} else if (installDropdown) {
|
||||
installDropdown.style.display = 'none';
|
||||
installDropdown.style.display = "none";
|
||||
}
|
||||
|
||||
// Fetch and display content
|
||||
const fileContent = await fetchFileContent(filePath);
|
||||
currentFileContent = fileContent;
|
||||
|
||||
|
||||
if (fileContent && codeEl) {
|
||||
codeEl.textContent = fileContent;
|
||||
} else if (codeEl) {
|
||||
codeEl.textContent = 'Failed to load file content. Click the button below to view on GitHub.';
|
||||
codeEl.textContent =
|
||||
"Failed to load file content. Click the button below to view on GitHub.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,27 +403,30 @@ async function openCollectionModal(
|
||||
downloadBtn: HTMLElement | null
|
||||
): Promise<void> {
|
||||
// Hide install dropdown and copy/download for collections
|
||||
if (installDropdown) installDropdown.style.display = 'none';
|
||||
if (copyBtn) copyBtn.style.display = 'none';
|
||||
if (downloadBtn) downloadBtn.style.display = 'none';
|
||||
if (installDropdown) installDropdown.style.display = "none";
|
||||
if (copyBtn) copyBtn.style.display = "none";
|
||||
if (downloadBtn) downloadBtn.style.display = "none";
|
||||
|
||||
// Show loading
|
||||
modalContent.innerHTML = '<div class="collection-loading">Loading collection...</div>';
|
||||
modalContent.innerHTML =
|
||||
'<div class="collection-loading">Loading collection...</div>';
|
||||
|
||||
// Load collections data if not cached
|
||||
if (!collectionsCache) {
|
||||
collectionsCache = await fetchData<CollectionsData>('collections.json');
|
||||
collectionsCache = await fetchData<CollectionsData>("collections.json");
|
||||
}
|
||||
|
||||
if (!collectionsCache) {
|
||||
modalContent.innerHTML = '<div class="collection-error">Failed to load collection data.</div>';
|
||||
modalContent.innerHTML =
|
||||
'<div class="collection-error">Failed to load collection data.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the collection
|
||||
const collection = collectionsCache.items.find(c => c.path === filePath);
|
||||
const collection = collectionsCache.items.find((c) => c.path === filePath);
|
||||
if (!collection) {
|
||||
modalContent.innerHTML = '<div class="collection-error">Collection not found.</div>';
|
||||
modalContent.innerHTML =
|
||||
'<div class="collection-error">Collection not found.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -386,33 +436,57 @@ async function openCollectionModal(
|
||||
// Render collection view
|
||||
modalContent.innerHTML = `
|
||||
<div class="collection-view">
|
||||
<div class="collection-description">${escapeHtml(collection.description || '')}</div>
|
||||
${collection.tags && collection.tags.length > 0 ? `
|
||||
<div class="collection-description">${escapeHtml(
|
||||
collection.description || ""
|
||||
)}</div>
|
||||
${
|
||||
collection.tags && collection.tags.length > 0
|
||||
? `
|
||||
<div class="collection-tags">
|
||||
${collection.tags.map(t => `<span class="resource-tag">${escapeHtml(t)}</span>`).join('')}
|
||||
${collection.tags
|
||||
.map((t) => `<span class="resource-tag">${escapeHtml(t)}</span>`)
|
||||
.join("")}
|
||||
</div>
|
||||
` : ''}
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<div class="collection-items-header">
|
||||
<strong>${collection.items.length} items in this collection</strong>
|
||||
</div>
|
||||
<div class="collection-items-list">
|
||||
${collection.items.map(item => `
|
||||
<div class="collection-item" data-path="${escapeHtml(item.path)}" data-type="${escapeHtml(item.kind)}">
|
||||
<span class="collection-item-icon">${getResourceIcon(item.kind)}</span>
|
||||
${collection.items
|
||||
.map(
|
||||
(item) => `
|
||||
<div class="collection-item" data-path="${escapeHtml(
|
||||
item.path
|
||||
)}" data-type="${escapeHtml(item.kind)}">
|
||||
<span class="collection-item-icon">${getResourceIcon(
|
||||
item.kind
|
||||
)}</span>
|
||||
<div class="collection-item-info">
|
||||
<div class="collection-item-name">${escapeHtml(item.path.split('/').pop() || item.path)}</div>
|
||||
${item.usage ? `<div class="collection-item-usage">${escapeHtml(item.usage)}</div>` : ''}
|
||||
<div class="collection-item-name">${escapeHtml(
|
||||
item.path.split("/").pop() || item.path
|
||||
)}</div>
|
||||
${
|
||||
item.usage
|
||||
? `<div class="collection-item-usage">${escapeHtml(
|
||||
item.usage
|
||||
)}</div>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
<span class="collection-item-type">${escapeHtml(item.kind)}</span>
|
||||
</div>
|
||||
`).join('')}
|
||||
`
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add click handlers to collection items
|
||||
modalContent.querySelectorAll('.collection-item').forEach(el => {
|
||||
el.addEventListener('click', () => {
|
||||
modalContent.querySelectorAll(".collection-item").forEach((el) => {
|
||||
el.addEventListener("click", () => {
|
||||
const path = (el as HTMLElement).dataset.path;
|
||||
const itemType = (el as HTMLElement).dataset.type;
|
||||
if (path && itemType) {
|
||||
@@ -427,26 +501,30 @@ async function openCollectionModal(
|
||||
* @param updateUrl - Whether to update the URL hash (default: true)
|
||||
*/
|
||||
export function closeModal(updateUrl = true): void {
|
||||
const modal = document.getElementById('file-modal');
|
||||
const installDropdown = document.getElementById('install-dropdown');
|
||||
|
||||
const modal = document.getElementById("file-modal");
|
||||
const installDropdown = document.getElementById("install-dropdown");
|
||||
|
||||
if (modal) {
|
||||
modal.classList.add('hidden');
|
||||
modal.classList.add("hidden");
|
||||
}
|
||||
if (installDropdown) {
|
||||
installDropdown.classList.remove('open');
|
||||
installDropdown.classList.remove("open");
|
||||
}
|
||||
|
||||
|
||||
// Update URL for deep linking
|
||||
if (updateUrl) {
|
||||
updateHash(null);
|
||||
}
|
||||
|
||||
|
||||
// Return focus to trigger element
|
||||
if (triggerElement && typeof triggerElement.focus === 'function') {
|
||||
if (
|
||||
triggerElement &&
|
||||
triggerElement.isConnected &&
|
||||
typeof triggerElement.focus === "function"
|
||||
) {
|
||||
triggerElement.focus();
|
||||
}
|
||||
|
||||
|
||||
currentFilePath = null;
|
||||
currentFileContent = null;
|
||||
currentFileType = null;
|
||||
|
||||
Reference in New Issue
Block a user