mirror of
https://github.com/shadoll/sLogos.git
synced 2026-02-04 02:53:22 +00:00
fix: Update collection label retrieval to support titles and improve SVG error handling
This commit is contained in:
@@ -45,7 +45,8 @@
|
|||||||
dropdownOpen = false;
|
dropdownOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$: currentLabel = (collections.find(c => c.name === collection)?.label || "Logo Gallery").replace(/s$/, "");
|
$: currentCollectionObj = collections.find(c => c.name === collection);
|
||||||
|
$: currentLabel = (currentCollectionObj?.title || currentCollectionObj?.label || "Logo Gallery").replace(/s$/, "");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="main-header">
|
<header class="main-header">
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
<img src="favicon.svg" alt="Logo Gallery icon" />
|
<img src="favicon.svg" alt="Logo Gallery icon" />
|
||||||
</div>
|
</div>
|
||||||
<button class="collection-title-btn" on:click={handleTitleClick} aria-haspopup="listbox" aria-expanded={dropdownOpen}>
|
<button class="collection-title-btn" on:click={handleTitleClick} aria-haspopup="listbox" aria-expanded={dropdownOpen}>
|
||||||
{currentLabel} Gallery <span class="triangle">▼</span>
|
{currentLabel} <span class="triangle">▼</span>
|
||||||
</button>
|
</button>
|
||||||
{#if dropdownOpen}
|
{#if dropdownOpen}
|
||||||
<ul class="collection-dropdown" role="listbox">
|
<ul class="collection-dropdown" role="listbox">
|
||||||
@@ -72,7 +73,7 @@
|
|||||||
handleCollectionSelect(c.name);
|
handleCollectionSelect(c.name);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>{c.label} Gallery</li>
|
>{c.title} Gallery</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -107,6 +108,7 @@
|
|||||||
{getTagObj}
|
{getTagObj}
|
||||||
{compactMode}
|
{compactMode}
|
||||||
{setCompactMode}
|
{setCompactMode}
|
||||||
|
collection={currentCollectionObj}
|
||||||
/>
|
/>
|
||||||
<ListViewSwitcher
|
<ListViewSwitcher
|
||||||
{viewMode}
|
{viewMode}
|
||||||
|
|||||||
@@ -12,111 +12,122 @@
|
|||||||
let svgSource = ""; // Store the updated SVG source code
|
let svgSource = ""; // Store the updated SVG source code
|
||||||
|
|
||||||
async function fetchAndColorSvg() {
|
async function fetchAndColorSvg() {
|
||||||
const res = await fetch(path);
|
try {
|
||||||
let text = await res.text();
|
const res = await fetch(path);
|
||||||
if (!color) {
|
if (!res.ok) {
|
||||||
// No user-selected color, add currentColor to ensure theme colors are applied
|
svgHtml = `<svg width='100%' height='100%' viewBox='0 0 64 64' fill='none' xmlns='http://www.w3.org/2000/svg'><rect width='64' height='64' fill='#eee'/><line x1='16' y1='16' x2='48' y2='48' stroke='#888' stroke-width='4'/><line x1='48' y1='16' x2='16' y2='48' stroke='#888' stroke-width='4'/></svg>`;
|
||||||
|
svgSource = svgHtml;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let text = await res.text();
|
||||||
|
if (!color) {
|
||||||
|
// No user-selected color, add currentColor to ensure theme colors are applied
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(text, "image/svg+xml");
|
||||||
|
const svg = doc.documentElement;
|
||||||
|
|
||||||
|
// Set currentColor on SVG element if no fill is specified
|
||||||
|
if (!svg.hasAttribute("fill")) {
|
||||||
|
svg.setAttribute("fill", "currentColor");
|
||||||
|
}
|
||||||
|
|
||||||
|
svgHtml = doc.documentElement.outerHTML;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Parse and update color only if user selected
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const doc = parser.parseFromString(text, "image/svg+xml");
|
const doc = parser.parseFromString(text, "image/svg+xml");
|
||||||
const svg = doc.documentElement;
|
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
||||||
|
const styleEls = Array.from(doc.querySelectorAll("style"));
|
||||||
// Set currentColor on SVG element if no fill is specified
|
styleEls.forEach((styleEl) => {
|
||||||
if (!svg.hasAttribute("fill")) {
|
const css = styleEl.textContent;
|
||||||
svg.setAttribute("fill", "currentColor");
|
// Only handle simple .class { ... } rules
|
||||||
}
|
const regex = /\.([\w-]+)\s*{([^}]*)}/g;
|
||||||
|
let match;
|
||||||
svgHtml = doc.documentElement.outerHTML;
|
while ((match = regex.exec(css))) {
|
||||||
return;
|
const className = match[1];
|
||||||
}
|
const rules = match[2];
|
||||||
// Parse and update color only if user selected
|
// Find all elements with this class
|
||||||
const parser = new DOMParser();
|
doc.querySelectorAll("." + className).forEach((el) => {
|
||||||
const doc = parser.parseFromString(text, "image/svg+xml");
|
rules.split(";").forEach((rule) => {
|
||||||
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
const [prop, value] = rule.split(":").map((s) => s && s.trim());
|
||||||
const styleEls = Array.from(doc.querySelectorAll("style"));
|
if (prop && value) {
|
||||||
styleEls.forEach((styleEl) => {
|
// Apply all style properties, not just fill/stroke
|
||||||
const css = styleEl.textContent;
|
el.setAttribute(
|
||||||
// Only handle simple .class { ... } rules
|
prop.replace(/-([a-z])/g, (g) => g[1].toUpperCase()),
|
||||||
const regex = /\.([\w-]+)\s*{([^}]*)}/g;
|
value,
|
||||||
let match;
|
);
|
||||||
while ((match = regex.exec(css))) {
|
}
|
||||||
const className = match[1];
|
});
|
||||||
const rules = match[2];
|
|
||||||
// Find all elements with this class
|
|
||||||
doc.querySelectorAll("." + className).forEach((el) => {
|
|
||||||
rules.split(";").forEach((rule) => {
|
|
||||||
const [prop, value] = rule.split(":").map((s) => s && s.trim());
|
|
||||||
if (prop && value) {
|
|
||||||
// Apply all style properties, not just fill/stroke
|
|
||||||
el.setAttribute(
|
|
||||||
prop.replace(/-([a-z])/g, (g) => g[1].toUpperCase()),
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
});
|
// Remove all <style> elements
|
||||||
// Remove all <style> elements
|
styleEls.forEach((styleEl) => styleEl.remove());
|
||||||
styleEls.forEach((styleEl) => styleEl.remove());
|
// Handle the new format with targets and sets if available
|
||||||
// Handle the new format with targets and sets if available
|
if (targets && sets && activeSet && typeof activeSet === 'string' && sets[activeSet]) {
|
||||||
if (targets && sets && activeSet && typeof activeSet === 'string' && sets[activeSet]) {
|
try {
|
||||||
try {
|
// Get the color assignments from the active set
|
||||||
// Get the color assignments from the active set
|
const colorAssignments = sets[activeSet];
|
||||||
const colorAssignments = sets[activeSet];
|
|
||||||
|
|
||||||
// Apply each target-color pair
|
// Apply each target-color pair
|
||||||
for (const [targetName, colorName] of Object.entries(colorAssignments)) {
|
for (const [targetName, colorName] of Object.entries(colorAssignments)) {
|
||||||
if (targets[targetName] && colors && colors[colorName]) {
|
if (targets[targetName] && colors && colors[colorName]) {
|
||||||
// Get the selector and determine if it's for fill or stroke
|
// Get the selector and determine if it's for fill or stroke
|
||||||
const targetInfo = targets[targetName];
|
const targetInfo = targets[targetName];
|
||||||
|
|
||||||
// Parse the selector to extract the target and attribute (fill/stroke)
|
// Parse the selector to extract the target and attribute (fill/stroke)
|
||||||
let selector, attribute;
|
let selector, attribute;
|
||||||
|
|
||||||
if (typeof targetInfo === 'string') {
|
if (typeof targetInfo === 'string') {
|
||||||
if (targetInfo.includes('&stroke')) {
|
if (targetInfo.includes('&stroke')) {
|
||||||
// Format: "#element&stroke" - target stroke attribute
|
// Format: "#element&stroke" - target stroke attribute
|
||||||
selector = targetInfo.split('&stroke')[0];
|
selector = targetInfo.split('&stroke')[0];
|
||||||
attribute = 'stroke';
|
attribute = 'stroke';
|
||||||
} else if (targetInfo.includes('&fill')) {
|
} else if (targetInfo.includes('&fill')) {
|
||||||
// Format: "#element&fill" - target fill attribute
|
// Format: "#element&fill" - target fill attribute
|
||||||
selector = targetInfo.split('&fill')[0];
|
selector = targetInfo.split('&fill')[0];
|
||||||
attribute = 'fill';
|
attribute = 'fill';
|
||||||
|
} else {
|
||||||
|
// Default is fill if not specified
|
||||||
|
selector = targetInfo;
|
||||||
|
attribute = 'fill';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Default is fill if not specified
|
// Fallback for older format
|
||||||
selector = targetInfo;
|
selector = targetInfo;
|
||||||
attribute = 'fill';
|
attribute = 'fill';
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Fallback for older format
|
// Proceed with selecting elements and applying colors
|
||||||
selector = targetInfo;
|
const targetElements = doc.querySelectorAll(selector);
|
||||||
attribute = 'fill';
|
const targetColor = colors[colorName];
|
||||||
|
|
||||||
|
// Apply the color to all elements matching this selector
|
||||||
|
targetElements.forEach(el => {
|
||||||
|
if (colorName === "none") {
|
||||||
|
// Special case for 'none' value
|
||||||
|
el.setAttribute(attribute, "none");
|
||||||
|
} else if (attribute === 'fill') {
|
||||||
|
el.setAttribute("fill", targetColor);
|
||||||
|
} else if (attribute === 'stroke') {
|
||||||
|
el.setAttribute("stroke", targetColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proceed with selecting elements and applying colors
|
|
||||||
const targetElements = doc.querySelectorAll(selector);
|
|
||||||
const targetColor = colors[colorName];
|
|
||||||
|
|
||||||
// Apply the color to all elements matching this selector
|
|
||||||
targetElements.forEach(el => {
|
|
||||||
if (colorName === "none") {
|
|
||||||
// Special case for 'none' value
|
|
||||||
el.setAttribute(attribute, "none");
|
|
||||||
} else if (attribute === 'fill') {
|
|
||||||
el.setAttribute("fill", targetColor);
|
|
||||||
} else if (attribute === 'stroke') {
|
|
||||||
el.setAttribute("stroke", targetColor);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error applying color set:", err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
console.error("Error applying color set:", err);
|
|
||||||
}
|
}
|
||||||
|
svgHtml = doc.documentElement.outerHTML;
|
||||||
|
// Update the svgSource property to store the modified SVG code
|
||||||
|
svgSource = doc.documentElement.outerHTML;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching or processing SVG:", error);
|
||||||
|
svgHtml = `<svg width='100%' height='100%' viewBox='0 0 64 64' fill='none' xmlns='http://www.w3.org/2000/svg'><rect width='64' height='64' fill='#eee'/><line x1='16' y1='16' x2='48' y2='48' stroke='#888' stroke-width='4'/><line x1='48' y1='16' x2='16' y2='48' stroke='#888' stroke-width='4'/></svg>`;
|
||||||
|
svgSource = svgHtml;
|
||||||
}
|
}
|
||||||
svgHtml = doc.documentElement.outerHTML;
|
|
||||||
// Update the svgSource property to store the modified SVG code
|
|
||||||
svgSource = doc.documentElement.outerHTML;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export the svgSource so it can be accessed from outside
|
// Export the svgSource so it can be accessed from outside
|
||||||
|
|||||||
Reference in New Issue
Block a user