Files

172 lines
4.3 KiB
JavaScript

/**
* Syntax Highlighting (Placeholder)
*
* Future implementation for prompt syntax highlighting:
* - Color-code [scheduling:syntax:when]
* - Color-code (emphasis:1.2)
* - Color-code [A|B|C] alternation
* - Custom textarea with overlay (complex)
*/
import { app } from "../../../scripts/app.js";
// Syntax patterns for highlighting
export const SYNTAX_PATTERNS = {
// Emphasis: (text:1.2), (text), [text]
emphasis: /\(([^():]+)(?::(\d+\.?\d*))?\)/g,
deemphasis: /\[([^\[\]|:]+)\]/g,
// Scheduling: [from:to:when]
scheduling: /\[([^:\[\]]+):([^:\[\]]+):(\d+\.?\d*)\]/g,
addAt: /\[([^:\[\]]+):(\d+\.?\d*)\]/g,
removeAt: /\[([^:\[\]]+)::(\d+\.?\d*)\]/g,
// Alternation: [A|B|C]
alternation: /\[([^\[\]]+\|[^\[\]]+)\]/g,
// BREAK keyword
breakKeyword: /\bBREAK\b/g,
};
// Color scheme for syntax highlighting
export const SYNTAX_COLORS = {
emphasis: "#f39c12", // Orange
deemphasis: "#9b59b6", // Purple
scheduling: "#3498db", // Blue
alternation: "#2ecc71", // Green
breakKeyword: "#e74c3c", // Red
number: "#1abc9c", // Teal
};
/**
* Parse prompt text and identify syntax elements
* @param {string} text - The prompt text
* @returns {Array} Array of syntax elements with positions
*/
export function parseSyntaxElements(text) {
const elements = [];
// TODO: Implement proper parsing
// This is complex because we need to handle nesting
return elements;
}
/**
* Create highlighted HTML from prompt text
* @param {string} text - The prompt text
* @returns {string} HTML with syntax highlighting
*/
export function createHighlightedHtml(text) {
// TODO: Implement syntax highlighting
// This requires careful handling of nested syntax
return escapeHtml(text);
}
/**
* Escape HTML characters
* @param {string} str - String to escape
* @returns {string} Escaped string
*/
function escapeHtml(str) {
const div = document.createElement("div");
div.textContent = str;
return div.innerHTML;
}
/**
* Create an overlay layer for syntax highlighting
* This creates a mirror div behind the textarea that shows colored syntax
* @param {HTMLTextAreaElement} textarea - The textarea to highlight
* @returns {Object} Object with overlay element and update function
*/
export function createSyntaxOverlay(textarea) {
// Create container
const container = document.createElement("div");
container.className = "a1111-syntax-overlay-container";
container.style.cssText = `
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
overflow: hidden;
`;
// Create mirror div
const mirror = document.createElement("div");
mirror.className = "a1111-syntax-mirror";
mirror.style.cssText = `
position: absolute;
top: 0;
left: 0;
right: 0;
white-space: pre-wrap;
word-wrap: break-word;
pointer-events: none;
color: transparent;
overflow: hidden;
`;
container.appendChild(mirror);
// Update function
const update = () => {
const html = createHighlightedHtml(textarea.value);
mirror.innerHTML = html;
};
// Sync scroll
const syncScroll = () => {
mirror.scrollTop = textarea.scrollTop;
mirror.scrollLeft = textarea.scrollLeft;
};
return {
container,
mirror,
update,
syncScroll,
};
}
// Extension registration placeholder
// Uncomment when implementing syntax highlighting
/*
app.registerExtension({
name: "A1111PromptNode.SyntaxHighlight",
async nodeCreated(node) {
if (
node.comfyClass !== "A1111Prompt" &&
node.comfyClass !== "A1111PromptNegative"
)
return;
const textWidget = node.widgets?.find((w) => w.name === "text");
if (!textWidget?.inputEl) return;
const textarea = textWidget.inputEl;
const { container, update, syncScroll } = createSyntaxOverlay(textarea);
// Insert overlay
textarea.parentNode.style.position = "relative";
textarea.parentNode.insertBefore(container, textarea);
// Copy styles from textarea
const computed = window.getComputedStyle(textarea);
container.firstChild.style.font = computed.font;
container.firstChild.style.padding = computed.padding;
container.firstChild.style.lineHeight = computed.lineHeight;
// Add event listeners
textarea.addEventListener("input", update);
textarea.addEventListener("scroll", syncScroll);
// Initial update
update();
},
});
*/