@marvalt/wparser 0.1.49 → 0.1.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2083,45 +2083,13 @@ function extractVideoIframeFromInnerBlocks(block) {
2083
2083
  */
2084
2084
  function extractBackgroundColor(block, context) {
2085
2085
  const attrs = block.attributes || {};
2086
- // Try multiple possible attribute names for background color
2087
- // WordPress can store it as backgroundColor, background, or in style
2088
- let wpColorName = attrs['backgroundColor'] ||
2089
- attrs['background'] ||
2090
- attrs['backgroundColorSlug'] ||
2091
- null;
2092
- // If not found in attributes, check className for WordPress color classes
2093
- // WordPress uses classes like: has-accent-4-background-color, has-contrast-background-color
2094
- if (!wpColorName && attrs['className']) {
2095
- const className = attrs['className'];
2096
- const colorMatch = className.match(/has-([\w-]+)-background-color/);
2097
- if (colorMatch && colorMatch[1]) {
2098
- // Convert kebab-case to slug (e.g., "accent-4" stays "accent-4", "contrast" stays "contrast")
2099
- wpColorName = colorMatch[1];
2100
- }
2101
- }
2102
- // Debug logging in development
2103
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2104
- if (!wpColorName && context.colorMapper) {
2105
- console.log('🔍 extractBackgroundColor - No backgroundColor found in block:', {
2106
- blockName: block.name,
2107
- hasClassName: !!attrs['className'],
2108
- className: attrs['className'],
2109
- hasStyle: !!attrs['style'],
2110
- availableAttrs: Object.keys(attrs),
2111
- });
2112
- }
2113
- }
2086
+ const wpColorName = attrs['backgroundColor'] || attrs['background'];
2114
2087
  if (!wpColorName || typeof wpColorName !== 'string') {
2115
2088
  return null;
2116
2089
  }
2117
2090
  // Use colorMapper from context if available
2118
2091
  if (context.colorMapper) {
2119
- const result = context.colorMapper(wpColorName);
2120
- // Debug logging
2121
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2122
- console.log('🎨 extractBackgroundColor - Mapped', wpColorName, '→', result);
2123
- }
2124
- return result;
2092
+ return context.colorMapper(wpColorName);
2125
2093
  }
2126
2094
  // Fallback: return null (no background applied)
2127
2095
  return null;
@@ -2136,102 +2104,34 @@ function extractBackgroundColor(block, context) {
2136
2104
  */
2137
2105
  function extractTextColor(block, context) {
2138
2106
  const attrs = block.attributes || {};
2139
- const mapper = context.colorMapper;
2140
- // Try multiple possible attribute names for text color
2141
- let wpColorName = attrs['textColor'] ||
2142
- attrs['text'] ||
2143
- attrs['textColorSlug'] ||
2144
- null;
2145
- // If not found in attributes, check className for WordPress color classes
2146
- // WordPress uses classes like: has-accent-4-color, has-contrast-color
2147
- // Note: We need to avoid matching has-{color}-background-color, so we check for -color that's not followed by -background
2148
- if (!wpColorName && attrs['className']) {
2149
- const className = attrs['className'];
2150
- // Match: has-{color}-color (text color class, not background-color)
2151
- // This regex matches "has-accent-4-color" but not "has-accent-4-background-color"
2152
- const colorMatch = className.match(/has-([\w-]+)-color(?!-background)/);
2153
- if (colorMatch && colorMatch[1]) {
2154
- wpColorName = colorMatch[1];
2155
- }
2156
- // Enhanced debug logging
2157
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2158
- if (!wpColorName) {
2159
- const hasColorClass = className.includes('-color');
2160
- if (hasColorClass && context.colorMapper) {
2161
- console.log('🔍 extractTextColor - Found color class in className but no match:', {
2162
- blockName: block.name,
2163
- className: className,
2164
- colorClasses: className.split(' ').filter(c => c.includes('-color')),
2165
- allAttrs: Object.keys(attrs),
2166
- });
2167
- }
2168
- }
2169
- else {
2170
- console.log('✅ extractTextColor - Found color in className:', wpColorName);
2171
- }
2172
- }
2173
- }
2107
+ const wpColorName = attrs['textColor'] || attrs['text'];
2174
2108
  if (!wpColorName || typeof wpColorName !== 'string') {
2175
- wpColorName = null;
2109
+ return null;
2110
+ }
2111
+ // Special handling for common WordPress color names when used as text color
2112
+ // These mappings take precedence because text color semantics differ from background color
2113
+ const textColorMap = {
2114
+ 'contrast': 'text-gray-900', // Contrast text is typically dark/black (opposite of contrast background)
2115
+ 'base': 'text-white', // Base text on dark backgrounds
2116
+ };
2117
+ // Check special text color mappings first
2118
+ if (textColorMap[wpColorName]) {
2119
+ return textColorMap[wpColorName];
2176
2120
  }
2177
2121
  // Use colorMapper from context if available
2178
- // Note: colorMapper returns combined classes like "bg-[#FBFAF3] text-gray-900"
2179
- // We need to extract just the text color part
2180
- if (mapper && wpColorName) {
2181
- const mapped = mapper(wpColorName);
2122
+ // Note: colorMapper might return combined classes like "bg-gray-900 text-white"
2123
+ // We'll extract just the text color part
2124
+ if (context.colorMapper) {
2125
+ const mapped = context.colorMapper(wpColorName);
2182
2126
  if (mapped) {
2183
- // If the mapper provided a background arbitrary value, derive a text color class directly from it
2184
- const bgArbitrary = mapped.match(/\bbg-\[([^\]]+)\]/);
2185
- if (bgArbitrary && bgArbitrary[1]) {
2186
- const derivedText = `text-[${bgArbitrary[1]}]`;
2187
- return derivedText;
2127
+ // If the mapped class includes text color (e.g., "bg-gray-900 text-white"),
2128
+ // extract just the text color part
2129
+ const textColorMatch = mapped.match(/\btext-\S+/);
2130
+ if (textColorMatch) {
2131
+ return textColorMatch[0];
2188
2132
  }
2189
- // Extract text color classes (e.g., "text-white", "text-gray-900", "text-[#123456]")
2190
- // Match text- classes including arbitrary values in brackets
2191
- const textColorMatch = mapped.match(/\btext-(\[[^\]]+\]|[\w-]+)/g);
2192
- if (textColorMatch && textColorMatch.length > 0) {
2193
- // Return the last text color class (in case there are multiple)
2194
- const result = textColorMatch[textColorMatch.length - 1];
2195
- // Debug logging
2196
- if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
2197
- console.log('🎨 extractTextColor - Mapped', wpColorName, '→', result, '(from:', mapped, ')');
2198
- }
2199
- return result;
2200
- }
2201
- // If no text color class found, try to determine from the background color
2202
- // For theme palette colors, we can infer text color based on brightness
2203
- // But for now, return null if no text color is in the mapped result
2204
2133
  }
2205
2134
  }
2206
- // Fallback: return null (no text color applied, will inherit from parent)
2207
- return null;
2208
- }
2209
- /**
2210
- * Infer a readable text color class based on a background class string.
2211
- * Supports bg-[#hex] and bg-[rgb(...)].
2212
- */
2213
- function inferTextColorFromBackground(backgroundClass) {
2214
- if (!backgroundClass)
2215
- return null;
2216
- // Try to extract hex color from arbitrary value class bg-[#xxxxxx]
2217
- const hexMatch = backgroundClass.match(/bg-\[#?([0-9a-fA-F]{6})\]/);
2218
- if (hexMatch) {
2219
- const hex = hexMatch[1];
2220
- const r = parseInt(hex.slice(0, 2), 16);
2221
- const g = parseInt(hex.slice(2, 4), 16);
2222
- const b = parseInt(hex.slice(4, 6), 16);
2223
- const brightness = (r * 299 + g * 587 + b * 114) / 1000;
2224
- return brightness < 140 ? 'text-white' : 'text-gray-900';
2225
- }
2226
- // Try rgb() form
2227
- const rgbMatch = backgroundClass.match(/bg-\[rgb\((\d+),\s*(\d+),\s*(\d+)\)\]/i);
2228
- if (rgbMatch) {
2229
- const r = parseInt(rgbMatch[1], 10);
2230
- const g = parseInt(rgbMatch[2], 10);
2231
- const b = parseInt(rgbMatch[3], 10);
2232
- const brightness = (r * 299 + g * 587 + b * 114) / 1000;
2233
- return brightness < 140 ? 'text-white' : 'text-gray-900';
2234
- }
2235
2135
  return null;
2236
2136
  }
2237
2137
  /**
@@ -2375,9 +2275,6 @@ const Paragraph = ({ block, context }) => {
2375
2275
  const attrs = block.attributes || {};
2376
2276
  const textAlign = getTextAlignClasses(attrs['align']);
2377
2277
  const spacing = getSpacing(context.spacingConfig || context.registry.spacingConfig, 'paragraph', 'my-6');
2378
- // Extract text color if specified
2379
- const textColor = extractTextColor(block, context);
2380
- const textColorClass = textColor || '';
2381
2278
  // Check if innerHTML contains HTML elements (like links, strong, em, etc.)
2382
2279
  const hasHTML = block.innerHTML && /<[a-z][\s\S]*>/i.test(block.innerHTML);
2383
2280
  // Check if content contains shortcodes (check both HTML and text content)
@@ -2413,17 +2310,17 @@ const Paragraph = ({ block, context }) => {
2413
2310
  const hasBlockLevelContent = React.Children.toArray(parts).some((part) => isBlockLevelElement(part));
2414
2311
  if (hasBlockLevelContent) {
2415
2312
  // Render block-level content without <p> wrapper, but add spacing wrapper
2416
- return jsxRuntimeExports.jsx("div", { className: buildClassName(spacing, textColorClass), children: parts });
2313
+ return jsxRuntimeExports.jsx("div", { className: spacing, children: parts });
2417
2314
  }
2418
2315
  // Render shortcode parts inside paragraph (shortcodes are processed as React components)
2419
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: parts });
2316
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: parts });
2420
2317
  }
2421
2318
  // If innerHTML contains HTML elements but no shortcodes, render it directly (preserves links, formatting, etc.)
2422
2319
  if (hasHTML && block.innerHTML) {
2423
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), dangerouslySetInnerHTML: { __html: htmlContent } });
2320
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), dangerouslySetInnerHTML: { __html: htmlContent } });
2424
2321
  }
2425
2322
  // No HTML and no shortcodes, just render plain text content
2426
- return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign, textColorClass), children: textContent });
2323
+ return jsxRuntimeExports.jsx("p", { className: buildClassName(spacing, textAlign), children: textContent });
2427
2324
  };
2428
2325
  const Heading = ({ block, children, context }) => {
2429
2326
  const attrs = block.attributes || {};
@@ -2436,13 +2333,10 @@ const Heading = ({ block, children, context }) => {
2436
2333
  const sizeClass = fontSize || (level === 1 ? 'text-4xl' : level === 2 ? 'text-3xl' : level === 3 ? 'text-2xl' : 'text-xl');
2437
2334
  // Get spacing from config with improved defaults
2438
2335
  const spacingClass = getHeadingSpacing(context.spacingConfig || context.registry.spacingConfig, level);
2439
- // Extract text color if specified, otherwise fall back to heading var (set by dstyler) or inherit
2336
+ // Extract text color if specified, otherwise inherit from parent
2440
2337
  const textColor = extractTextColor(block, context);
2441
- const isFallbackHeadingColor = !textColor;
2442
- const textColorClass = textColor || 'text-[var(--dstyler-color-heading)]';
2443
- // Inline style ensures heading color wins over inherited parent text classes
2444
- const inlineStyle = isFallbackHeadingColor ? { color: 'var(--dstyler-color-heading)' } : undefined;
2445
- return (jsxRuntimeExports.jsx(Tag, { className: buildClassName('font-bold', textColorClass, sizeClass, textAlign, spacingClass), style: inlineStyle, children: children ?? content }));
2338
+ const textColorClass = textColor || ''; // Don't hardcode - let it inherit from parent
2339
+ return (jsxRuntimeExports.jsx(Tag, { className: buildClassName('font-bold', textColorClass, sizeClass, textAlign, spacingClass), children: children ?? content }));
2446
2340
  };
2447
2341
  const Image = ({ block, context }) => {
2448
2342
  const imageAttrs = getImageAttributes(block);
@@ -2535,8 +2429,6 @@ const Group = ({ block, children, context }) => {
2535
2429
  const layout = attrs['layout'];
2536
2430
  // Extract background color using color mapper
2537
2431
  const backgroundColor = extractBackgroundColor(block, context);
2538
- // Extract text color (apply on the wrapper so children inherit)
2539
- const textColor = extractTextColor(block, context) || inferTextColorFromBackground(backgroundColor);
2540
2432
  // Determine if this is a section-level group (has alignment) or content-level
2541
2433
  const isSection = align === 'full' || align === 'wide';
2542
2434
  const containerClass = getContainerClasses(align, layout);
@@ -2550,8 +2442,8 @@ const Group = ({ block, children, context }) => {
2550
2442
  ? 'container'
2551
2443
  : containerClass;
2552
2444
  // Build className with background color if present
2553
- const className = buildClassName(finalContainerClass, spacingClass, backgroundColor, // This will be null if no mapping, which is fine
2554
- textColor);
2445
+ const className = buildClassName(finalContainerClass, spacingClass, backgroundColor // This will be null if no mapping, which is fine
2446
+ );
2555
2447
  return (jsxRuntimeExports.jsx("div", { className: className, children: children }));
2556
2448
  };
2557
2449
  const Columns = ({ block, children }) => {
@@ -2565,10 +2457,9 @@ const Column = ({ block, children, context }) => {
2565
2457
  const width = attrs['width'];
2566
2458
  // Extract background color using color mapper
2567
2459
  const backgroundColor = extractBackgroundColor(block, context);
2568
- const textColor = extractTextColor(block, context) || inferTextColorFromBackground(backgroundColor);
2569
2460
  // Handle column width (e.g., "50%" becomes flex-basis)
2570
2461
  const style = width ? { flexBasis: width } : undefined;
2571
- return (jsxRuntimeExports.jsx("div", { className: buildClassName('space-y-4 p-6 rounded-lg', backgroundColor, textColor), style: style, children: children }));
2462
+ return (jsxRuntimeExports.jsx("div", { className: buildClassName('space-y-4 p-6 rounded-lg', backgroundColor), style: style, children: children }));
2572
2463
  };
2573
2464
  const Separator = () => jsxRuntimeExports.jsx("hr", { className: "border-gray-200 my-8" });
2574
2465
  const ButtonBlock = ({ block, context }) => {
@@ -3128,7 +3019,6 @@ exports.getImageAttributes = getImageAttributes;
3128
3019
  exports.getImageUrl = getImageUrl;
3129
3020
  exports.getSectionSpacingClasses = getSectionSpacingClasses;
3130
3021
  exports.getTextAlignClasses = getTextAlignClasses;
3131
- exports.inferTextColorFromBackground = inferTextColorFromBackground;
3132
3022
  exports.isCloudflareImageUrl = isCloudflareImageUrl;
3133
3023
  exports.isValidCloudflareUrl = isValidCloudflareUrl;
3134
3024
  exports.matchesPattern = matchesPattern;