mirror of
https://github.com/HeyPuter/puter.git
synced 2026-01-06 13:10:24 -06:00
Update new_context_menu_item.js
This commit is contained in:
@@ -23,234 +23,6 @@ import UIAlert from '../UI/UIAlert.js';
|
||||
// Initialize the favicon cache if it doesn't exist
|
||||
window.favicon_cache = window.favicon_cache || {};
|
||||
|
||||
// Single, unified function for applying favicons to weblink items
|
||||
function applyWeblinkIcon(item, faviconUrl, url) {
|
||||
// Validate inputs
|
||||
if (!item || !faviconUrl) return false;
|
||||
|
||||
const $item = $(item);
|
||||
if (!$item.length) return false;
|
||||
|
||||
try {
|
||||
// Clear any existing icons first to prevent stacking
|
||||
$item.find('img.item-icon').remove();
|
||||
|
||||
// Create a fresh icon element
|
||||
const $icon = $('<img class="item-icon weblink-icon">');
|
||||
$item.prepend($icon);
|
||||
|
||||
// Set core attributes
|
||||
$icon.attr({
|
||||
'src': faviconUrl,
|
||||
'data-icon': faviconUrl
|
||||
});
|
||||
|
||||
// Handle loading errors
|
||||
$icon.on('error', function() {
|
||||
this.src = window.icons['link.svg'];
|
||||
});
|
||||
|
||||
// Set essential item attributes
|
||||
$item.attr({
|
||||
'data-icon': faviconUrl,
|
||||
'data-weblink': 'true'
|
||||
});
|
||||
|
||||
// Store in favicon cache
|
||||
if (url) {
|
||||
try {
|
||||
const domain = new URL(url).hostname;
|
||||
window.favicon_cache[domain] = faviconUrl;
|
||||
|
||||
// Also store in localStorage for persistence
|
||||
localStorage.setItem(`favicon_${domain}`, faviconUrl);
|
||||
|
||||
// Add domain to item attributes
|
||||
$item.attr('data-domain', domain);
|
||||
} catch (e) {
|
||||
console.error("Error processing URL:", e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error("Error applying weblink icon:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up global CSS once at startup
|
||||
(function setupWeblinkStyles() {
|
||||
let styleTag = document.getElementById('weblink-global-styles');
|
||||
if (!styleTag) {
|
||||
styleTag = document.createElement('style');
|
||||
styleTag.id = 'weblink-global-styles';
|
||||
document.head.appendChild(styleTag);
|
||||
|
||||
styleTag.textContent = `
|
||||
/* Ensure weblink icons are always visible */
|
||||
.item[data-weblink="true"] .item-icon,
|
||||
.item[data-name$=".weblink"] .item-icon,
|
||||
.weblink-icon {
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
display: block !important;
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
margin: 0 auto !important;
|
||||
background-size: contain !important;
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
/* Hide .weblink extension completely */
|
||||
.item[data-name$=".weblink"] .item-name {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Show only the site name */
|
||||
.item[data-name$=".weblink"] .item-name:after {
|
||||
content: attr(data-display-name);
|
||||
visibility: visible;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Prevent multiple icons */
|
||||
.item[data-weblink="true"] img.item-icon ~ img.item-icon {
|
||||
display: none !important;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
// Add a global hook to modify file names when displayed
|
||||
if (!window.originalItemNameDisplay) {
|
||||
// Backup the original function if it exists
|
||||
window.originalItemNameDisplay = window.update_item_name;
|
||||
|
||||
// Override the function that updates item names
|
||||
window.update_item_name = function(item, newName) {
|
||||
// Call the original function first
|
||||
if (window.originalItemNameDisplay) {
|
||||
window.originalItemNameDisplay(item, newName);
|
||||
}
|
||||
|
||||
// Then check if this is a weblink and modify the display
|
||||
if (item && $(item).length) {
|
||||
const $item = $(item);
|
||||
const itemName = $item.attr('data-name') || newName;
|
||||
|
||||
// Check if this is a weblink
|
||||
if (itemName && itemName.toLowerCase().endsWith('.weblink')) {
|
||||
// Extract the simple name (without extension)
|
||||
const nameWithoutExt = itemName.replace(/\.weblink$/i, '');
|
||||
|
||||
// Find the name element
|
||||
const $nameEl = $item.find('.item-name');
|
||||
if ($nameEl.length) {
|
||||
// Store the full name in data attribute
|
||||
$nameEl.attr('data-full-name', itemName);
|
||||
$nameEl.attr('data-display-name', nameWithoutExt);
|
||||
|
||||
// Set the text directly
|
||||
$nameEl.text(nameWithoutExt);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
// Set up a global weblink item observer
|
||||
(function setupWeblinkObserver() {
|
||||
// Skip if already initialized
|
||||
if (window.weblinkObserverInitialized) return;
|
||||
window.weblinkObserverInitialized = true;
|
||||
|
||||
// Function to find and fix weblink items
|
||||
const fixWeblinkItems = () => {
|
||||
// Find all weblink items
|
||||
const weblinkItems = document.querySelectorAll('.item[data-name$=".weblink"]');
|
||||
|
||||
weblinkItems.forEach(item => {
|
||||
const $item = $(item);
|
||||
|
||||
// Skip if already processed
|
||||
if ($item.attr('data-weblink-processed') === 'true') return;
|
||||
|
||||
// Apply icon
|
||||
const faviconUrl = $item.attr('data-icon') || $item.attr('data-favicon') || $item.attr('data-icon-url');
|
||||
const url = $item.attr('data-url');
|
||||
|
||||
// Apply icons first
|
||||
if (faviconUrl) {
|
||||
applyWeblinkIcon(item, faviconUrl, url);
|
||||
}
|
||||
|
||||
// Fix the display name
|
||||
const $nameEl = $item.find('.item-name');
|
||||
if ($nameEl.length) {
|
||||
const itemName = $item.attr('data-name');
|
||||
if (itemName) {
|
||||
// Strip extension
|
||||
const nameWithoutExt = itemName.replace(/\.weblink$/i, '');
|
||||
|
||||
// Apply to display name
|
||||
$nameEl.attr('data-full-name', itemName);
|
||||
$nameEl.attr('data-display-name', nameWithoutExt);
|
||||
$nameEl.text(nameWithoutExt);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark as processed to avoid duplicate processing
|
||||
$item.attr('data-weblink-processed', 'true');
|
||||
});
|
||||
};
|
||||
|
||||
// Run immediately
|
||||
fixWeblinkItems();
|
||||
|
||||
// Set up MutationObserver to watch for DOM changes
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
let shouldFix = false;
|
||||
|
||||
mutations.forEach(mutation => {
|
||||
// Check if we need to reapply icons and names
|
||||
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
||||
for (const node of mutation.addedNodes) {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
if (
|
||||
node.classList &&
|
||||
(node.classList.contains('item') || node.querySelector('.item'))
|
||||
) {
|
||||
shouldFix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (shouldFix) {
|
||||
fixWeblinkItems();
|
||||
}
|
||||
});
|
||||
|
||||
// Watch for changes to item names
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: ['data-name']
|
||||
});
|
||||
|
||||
// Also run when desktop refreshes
|
||||
document.addEventListener('desktop-refreshed', fixWeblinkItems);
|
||||
document.addEventListener('directory-loaded', fixWeblinkItems);
|
||||
})();
|
||||
|
||||
/**
|
||||
* Returns a context menu item to create a new folder and a variety of file types.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user