diff --git a/script.js b/script.js index d726227..34eeb3e 100644 --- a/script.js +++ b/script.js @@ -18,88 +18,88 @@ function extractVariables(text) { const regex = /\${([^}]+)}/g; const variables = []; let match; - + while ((match = regex.exec(text)) !== null) { - const [variable, defaultValue] = match[1].split(':').map(s => s.trim()); - variables.push({ name: variable, default: defaultValue || '' }); + const [variable, defaultValue] = match[1].split(":").map((s) => s.trim()); + variables.push({ name: variable, default: defaultValue || "" }); } - - return [...new Set(variables.map(v => JSON.stringify(v)))].map(v => JSON.parse(v)); // Remove duplicates + + return [...new Set(variables.map((v) => JSON.stringify(v)))].map((v) => + JSON.parse(v) + ); // Remove duplicates } function createVariableInputs(variables, container) { - const form = document.createElement('div'); - form.className = 'variable-form'; - - variables.forEach(variable => { - const wrapper = document.createElement('div'); - wrapper.className = 'variable-input-wrapper'; - - const label = document.createElement('label'); + const form = document.createElement("div"); + form.className = "variable-form"; + + variables.forEach((variable) => { + const wrapper = document.createElement("div"); + wrapper.className = "variable-input-wrapper"; + + const label = document.createElement("label"); label.textContent = variable.name; - label.style.fontWeight = '600'; - - const input = document.createElement('input'); - input.type = 'text'; - input.className = 'variable-input'; + label.style.fontWeight = "600"; + + const input = document.createElement("input"); + input.type = "text"; + input.className = "variable-input"; input.placeholder = variable.default || `Enter ${variable.name}`; input.dataset.variable = variable.name; - input.dataset.default = variable.default || ''; - + input.dataset.default = variable.default || ""; + wrapper.appendChild(label); wrapper.appendChild(input); form.appendChild(wrapper); }); - + container.appendChild(form); return form; } -// Function to update the prompt preview with user input -function updatePromptPreview(promptText, form) { - let previewText = promptText; - const inputs = form.querySelectorAll('.variable-input'); - - inputs.forEach(input => { - const value = input.value.trim(); - const variable = input.dataset.variable; - const defaultValue = input.dataset.default; - const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, 'g'); - let replacement; - if (value) { - // User entered value - replacement = value; - } else if (defaultValue) { - // Show default value with highlight - replacement = defaultValue; - } else { - // No value or default, show variable name - replacement = variable; - } - replacement = `${replacement}`; - - previewText = previewText.replace(pattern,replacement); - }); - - return previewText; -} -function updatedContent(promptText) { - // Check if content has variables +// Function to update the prompt preview with user input or default values +function updatePromptPreview(promptText, form) { const variables = extractVariables(promptText); - + if (variables.length === 0) { return promptText; // Return original text if no variables found } - - // Replace variables with their default values if they exist - let updatedText = promptText; - variables.forEach(variable => { - const pattern = new RegExp(`\\$\{${variable.name}[^}]*\}`, 'g'); - const replacement = variable.default || `${variable.name}`; - updatedText = updatedText.replace(pattern, replacement); - }); - - return updatedText; + + let previewText = promptText; + // Replace variables with their default values without editting (for prompt cards, copy buttons, chat) + if (!form) { + variables.forEach(variable => { + const pattern = new RegExp(`\\$\{${variable.name}[^}]*\}`, 'g'); + const replacement = variable.default || `${variable.name}`; + previewText = previewText.replace(pattern, replacement); + }); + } + // Replace variables according to the user inputs. + else { + const inputs = form.querySelectorAll(".variable-input"); + + inputs.forEach((input) => { + const value = input.value.trim(); + const variable = input.dataset.variable; + const defaultValue = input.dataset.default; + const pattern = new RegExp(`\\$\{${variable}[^}]*\}`, 'g'); + let replacement; + if (value) { + // User entered value + replacement = value; + } else if (defaultValue) { + // Show default value with highlight + replacement = defaultValue; + } else { + // No value or default, show variable name + replacement = variable; + } + replacement = `${replacement}`; + + previewText = previewText.replace(pattern, replacement); + }); + } + return previewText; } // Initialize everything after DOM loads @@ -216,11 +216,12 @@ async function initializeSearch() { const searchTerm = e.target.value.toLowerCase(); const filteredPrompts = prompts.filter((prompt) => { - const matchesSearch = prompt.act.toLowerCase().includes(searchTerm) || + const matchesSearch = + prompt.act.toLowerCase().includes(searchTerm) || prompt.prompt.toLowerCase().includes(searchTerm); return isDevMode - ? (matchesSearch && prompt.for_devs === true) + ? matchesSearch && prompt.for_devs === true : matchesSearch; }); @@ -254,29 +255,32 @@ function updatePromptCount(filteredCount, totalCount) { function parseCSV(csv) { const lines = csv.split("\n"); - const headers = lines[0].split(",").map((header) => - header.replace(/"/g, "").trim() - ); + const headers = lines[0] + .split(",") + .map((header) => header.replace(/"/g, "").trim()); - return lines.slice(1).map((line) => { - const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || []; - const entry = {}; + return lines + .slice(1) + .map((line) => { + const values = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || []; + const entry = {}; - headers.forEach((header, index) => { - let value = values[index] ? values[index].replace(/"/g, "").trim() : ""; - // Remove backticks from the act/title - if (header === "act") { - value = value.replace(/`/g, ""); - } - // Convert 'TRUE'/'FALSE' strings to boolean for for_devs - if (header === "for_devs") { - value = value.toUpperCase() === "TRUE"; - } - entry[header] = value; - }); + headers.forEach((header, index) => { + let value = values[index] ? values[index].replace(/"/g, "").trim() : ""; + // Remove backticks from the act/title + if (header === "act") { + value = value.replace(/`/g, ""); + } + // Convert 'TRUE'/'FALSE' strings to boolean for for_devs + if (header === "for_devs") { + value = value.toUpperCase() === "TRUE"; + } + entry[header] = value; + }); - return entry; - }).filter((entry) => entry.act && entry.prompt); + return entry; + }) + .filter((entry) => entry.act && entry.prompt); } function displaySearchResults(results) { @@ -320,8 +324,9 @@ function displaySearchResults(results) { // Find the prompt card with matching title const cards = document.querySelectorAll(".prompt-card"); const targetCard = Array.from(cards).find((card) => { - const cardTitle = card.querySelector(".prompt-title").textContent - .replace(/\s+/g, " ") // Normalize whitespace + const cardTitle = card + .querySelector(".prompt-title") + .textContent.replace(/\s+/g, " ") // Normalize whitespace .replace(/[\n\r]/g, "") // Remove newlines .trim(); @@ -330,8 +335,10 @@ function displaySearchResults(results) { .replace(/[\n\r]/g, "") // Remove newlines .trim(); - return cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) || - searchTitle.toLowerCase().includes(cardTitle.toLowerCase()); + return ( + cardTitle.toLowerCase().includes(searchTitle.toLowerCase()) || + searchTitle.toLowerCase().includes(cardTitle.toLowerCase()) + ); }); if (targetCard) { @@ -351,8 +358,8 @@ function displaySearchResults(results) { if (isMobile) { // On mobile, scroll the window const cardRect = targetCard.getBoundingClientRect(); - const scrollTop = window.pageYOffset + cardRect.top - headerHeight - - 20; + const scrollTop = + window.pageYOffset + cardRect.top - headerHeight - 20; window.scrollTo({ top: scrollTop, @@ -362,8 +369,8 @@ function displaySearchResults(results) { // On desktop, scroll the main-content container const mainContent = document.querySelector(".main-content"); const cardRect = targetCard.getBoundingClientRect(); - const scrollTop = mainContent.scrollTop + cardRect.top - - headerHeight - 20; + const scrollTop = + mainContent.scrollTop + cardRect.top - headerHeight - 20; mainContent.scrollTo({ top: scrollTop, @@ -404,12 +411,13 @@ function filterPrompts() { .then((csvText) => { const prompts = parseCSV(csvText); const filteredPrompts = prompts.filter((prompt) => { - const matchesSearch = !searchTerm || + const matchesSearch = + !searchTerm || prompt.act.toLowerCase().includes(searchTerm) || prompt.prompt.toLowerCase().includes(searchTerm); return isDevMode - ? (matchesSearch && prompt.for_devs === true) + ? matchesSearch && prompt.for_devs === true : matchesSearch; }); @@ -418,7 +426,7 @@ function filterPrompts() { filteredPrompts.length, isDevMode ? prompts.filter((p) => p.for_devs === true).length - : prompts.length, + : prompts.length ); displaySearchResults(filteredPrompts); @@ -426,23 +434,29 @@ function filterPrompts() { const promptsGrid = document.querySelector(".prompts-grid"); if (promptsGrid) { const cards = promptsGrid.querySelectorAll( - ".prompt-card:not(.contribute-card)", + ".prompt-card:not(.contribute-card)" ); cards.forEach((card) => { const title = card.querySelector(".prompt-title").textContent.trim(); const matchingPrompt = prompts.find((p) => { - const pTitle = p.act.replace(/\s+/g, " ").replace(/[\n\r]/g, "") + const pTitle = p.act + .replace(/\s+/g, " ") + .replace(/[\n\r]/g, "") .trim(); - const cardTitle = title.replace(/\s+/g, " ").replace(/[\n\r]/g, "") + const cardTitle = title + .replace(/\s+/g, " ") + .replace(/[\n\r]/g, "") .trim(); - return pTitle.toLowerCase() === cardTitle.toLowerCase() || + return ( + pTitle.toLowerCase() === cardTitle.toLowerCase() || pTitle.toLowerCase().includes(cardTitle.toLowerCase()) || - cardTitle.toLowerCase().includes(pTitle.toLowerCase()); + cardTitle.toLowerCase().includes(pTitle.toLowerCase()) + ); }); // Show card if not in dev mode or if it's a dev prompt in dev mode card.style.display = - (!isDevMode || (matchingPrompt && matchingPrompt.for_devs === true)) + !isDevMode || (matchingPrompt && matchingPrompt.for_devs === true) ? "" : "none"; }); @@ -485,23 +499,29 @@ function createPromptCards() { const isDevMode = document.getElementById("devModeToggle").checked; const promptElements = document.querySelectorAll( - "h2[id^=act] + p + blockquote", + "h2[id^=act] + p + blockquote" ); promptElements.forEach((blockquote) => { - const title = blockquote.previousElementSibling.previousElementSibling - .textContent.trim(); + const title = + blockquote.previousElementSibling.previousElementSibling.textContent.trim(); const content = blockquote.textContent.trim(); // Find matching prompt in CSV const matchingPrompt = prompts.find((p) => { - const csvTitle = p.act.replace(/\s+/g, " ").replace(/[\n\r]/g, "") + const csvTitle = p.act + .replace(/\s+/g, " ") + .replace(/[\n\r]/g, "") .trim(); - const elementTitle = title.replace(/\s+/g, " ").replace(/[\n\r]/g, "") + const elementTitle = title + .replace(/\s+/g, " ") + .replace(/[\n\r]/g, "") .trim(); - return csvTitle.toLowerCase() === elementTitle.toLowerCase() || + return ( + csvTitle.toLowerCase() === elementTitle.toLowerCase() || csvTitle.toLowerCase().includes(elementTitle.toLowerCase()) || - elementTitle.toLowerCase().includes(csvTitle.toLowerCase()); + elementTitle.toLowerCase().includes(csvTitle.toLowerCase()) + ); }); // Extract contributor from the paragraph element @@ -546,9 +566,9 @@ function createPromptCards() {
${updatedContent(content)}
+${updatePromptPreview(content)}
@${contributor} `; @@ -585,7 +605,7 @@ function createPromptCards() { copyButton.addEventListener("click", async (e) => { e.stopPropagation(); try { - await navigator.clipboard.writeText(updatedContent(content)); + await navigator.clipboard.writeText(updatePromptPreview(content)); copyButton.innerHTML = `