migration wip
This commit is contained in:
@@ -139,31 +139,132 @@ function sanitizeHTML(html: string): string {
|
||||
|
||||
/**
|
||||
* Process WordPress shortcodes by converting them to HTML with proper styling
|
||||
* Also handles mixed scenarios where some content is already HTML with WordPress classes
|
||||
*/
|
||||
function processShortcodes(html: string): string {
|
||||
export function processShortcodes(html: string): string {
|
||||
let processed = html;
|
||||
|
||||
try {
|
||||
// Step 1: Convert any existing HTML with WordPress classes back to shortcode format
|
||||
// This ensures we have a consistent format to work with
|
||||
|
||||
// Handle vc_row and vc_row_inner
|
||||
processed = processed.replace(/<div[^>]*class=["'][^"']*(?:vc-row|vc_row|vc_row_inner)[^"']*["'][^>]*>/gi, (match) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
const isInner = match.includes('vc_row_inner') || match.includes('vc-row-inner');
|
||||
return `[${isInner ? 'vc_row_inner' : 'vc_row'} ${attrs}]`;
|
||||
});
|
||||
|
||||
// Handle vc_column and vc_column_inner
|
||||
processed = processed.replace(/<div[^>]*class=["'][^"']*(?:vc-column|vc_column|vc_column_inner)[^"']*["'][^>]*>/gi, (match) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
const isInner = match.includes('vc_column_inner') || match.includes('vc-column-inner');
|
||||
return `[${isInner ? 'vc_column_inner' : 'vc_column'} ${attrs}]`;
|
||||
});
|
||||
|
||||
// Handle vc_column_text
|
||||
processed = processed.replace(/<div[^>]*class=["'][^"']*(?:vc-column-text|vc_column_text)[^"']*["'][^>]*>/gi, (match) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
return `[vc_column_text ${attrs}]`;
|
||||
});
|
||||
|
||||
// Handle vc_single_image
|
||||
processed = processed.replace(/<img[^>]*class=["'][^"']*(?:vc-single-image|vc_single_image)[^"']*["'][^>]*>/gi, (match) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
const imageId = extractAttribute(attrs, 'data-wp-image-id') || extractAttribute(attrs, 'src');
|
||||
const width = extractAttribute(attrs, 'data-width') || '';
|
||||
return `[vc_single_image src="${imageId}" width="${width}"]`;
|
||||
});
|
||||
|
||||
// Handle vc_btn
|
||||
processed = processed.replace(/<a[^>]*class=["'][^"']*(?:vc-btn|vc_btn)[^"']*["'][^>]*>(.*?)<\/a>/gi, (match, content) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
const href = extractAttribute(attrs, 'href');
|
||||
const title = content;
|
||||
return `[vc_btn href="${href}" title="${title}"]`;
|
||||
});
|
||||
|
||||
// Handle vc_separator
|
||||
processed = processed.replace(/<hr[^>]*class=["'][^"']*(?:vc-separator|vc_separator)[^"']*["'][^>]*>/gi, (match) => {
|
||||
const attrs = extractAttributesFromHTML(match);
|
||||
return `[vc_separator ${attrs}]`;
|
||||
});
|
||||
|
||||
// Handle closing div tags by looking for matching opening shortcode tags
|
||||
// This is more complex, so we'll handle it carefully
|
||||
processed = processed.replace(/<\/div>/gi, (match, offset) => {
|
||||
const beforeContent = processed.substring(0, offset);
|
||||
const lastOpenTag = beforeContent.match(/\[(vc_row(?:_inner)?|vc_column(?:_inner)?|vc_column_text)\s*[^\]]*\]$/i);
|
||||
if (lastOpenTag) {
|
||||
return `[/${lastOpenTag[1]}]`;
|
||||
}
|
||||
// If no matching shortcode, keep the div closing tag
|
||||
return match;
|
||||
});
|
||||
|
||||
// Step 2: Process shortcode blocks into HTML
|
||||
processed = processVcRowShortcodes(processed);
|
||||
processed = processVcColumnShortcodes(processed);
|
||||
processed = processVcColumnTextShortcodes(processed);
|
||||
processed = processVcImageShortcodes(processed);
|
||||
processed = processVcButtonShortcodes(processed);
|
||||
processed = processVcSeparatorShortcodes(processed);
|
||||
processed = processVcVideoShortcodes(processed);
|
||||
processed = processBackgroundShortcodes(processed);
|
||||
|
||||
// Step 3: Check for unprocessed shortcodes and log them
|
||||
const unprocessedShortcodes = processed.match(/\[[^\]]*\]/g);
|
||||
if (unprocessedShortcodes && unprocessedShortcodes.length > 0) {
|
||||
console.warn('Unprocessed shortcodes found and will be removed:', unprocessedShortcodes);
|
||||
}
|
||||
|
||||
// Clean up any remaining shortcode artifacts
|
||||
// Only remove shortcodes that weren't processed
|
||||
processed = processed.replace(/\[[^\]]*\]/g, '');
|
||||
|
||||
// Step 4: Clean up any remaining empty div tags
|
||||
processed = processed.replace(/<div[^>]*>\s*<\/div>/g, '');
|
||||
|
||||
return processed;
|
||||
} catch (error) {
|
||||
console.error('Error processing shortcodes:', error);
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract attributes from HTML tag
|
||||
*/
|
||||
function extractAttributesFromHTML(html: string): string {
|
||||
// Extract all key="value" pairs from HTML tag
|
||||
const attrMatches = html.matchAll(/([a-zA-Z-]+)=["']([^"']*)["']/g);
|
||||
const attrs: string[] = [];
|
||||
|
||||
// Process shortcode blocks first (most complex)
|
||||
processed = processVcRowShortcodes(processed);
|
||||
processed = processVcColumnShortcodes(processed);
|
||||
processed = processVcColumnTextShortcodes(processed);
|
||||
processed = processVcImageShortcodes(processed);
|
||||
processed = processVcButtonShortcodes(processed);
|
||||
processed = processVcSeparatorShortcodes(processed);
|
||||
processed = processVcVideoShortcodes(processed);
|
||||
processed = processBackgroundShortcodes(processed);
|
||||
for (const match of attrMatches) {
|
||||
const key = match[1];
|
||||
const value = match[2];
|
||||
|
||||
// Map HTML data attributes back to shortcode attributes
|
||||
if (key.startsWith('data-')) {
|
||||
const shortcodeKey = key.replace('data-', '').replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
||||
attrs.push(`${shortcodeKey}="${value}"`);
|
||||
} else if (key === 'class') {
|
||||
// Skip class attribute for shortcode conversion
|
||||
continue;
|
||||
} else {
|
||||
attrs.push(`${key}="${value}"`);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any remaining shortcodes
|
||||
processed = processed.replace(/\[[^\]]*\]/g, '');
|
||||
|
||||
return processed;
|
||||
return attrs.join(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process [vc_row] shortcodes and convert to flex containers
|
||||
* Also handles underscored versions: vc_row, vc_row_inner
|
||||
*/
|
||||
function processVcRowShortcodes(html: string): string {
|
||||
return html.replace(/\[vc_row([^\]]*)\]([\s\S]*?)\[\/vc_row\]/g, (match, attrs, content) => {
|
||||
return html.replace(/\[vc_row(?:_inner)?([^\]]*)\]([\s\S]*?)\[\/vc_row(?:_inner)?\]/g, (match, attrs, content) => {
|
||||
const classes = ['vc-row', 'flex', 'flex-wrap', '-mx-4'];
|
||||
|
||||
// Parse attributes for background colors, images, etc.
|
||||
|
||||
Reference in New Issue
Block a user