@marvalt/wparser 0.1.7 → 0.1.10

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.esm.js CHANGED
@@ -1730,6 +1730,26 @@ const Paragraph = ({ block, context }) => {
1730
1730
  const hasShortcodes = /\[(\w+)/.test(content);
1731
1731
  if (hasShortcodes && context.registry.shortcodes) {
1732
1732
  const parts = renderTextWithShortcodes(content, context.registry);
1733
+ // Check if any part is a block-level element (section, div, etc.)
1734
+ // If so, render without wrapping in <p> to avoid DOM nesting violations
1735
+ const hasBlockLevelContent = React.Children.toArray(parts).some((part) => {
1736
+ if (React.isValidElement(part)) {
1737
+ const type = part.type;
1738
+ // Check for block-level HTML elements
1739
+ if (typeof type === 'string' && ['section', 'div', 'article', 'header', 'footer', 'aside', 'nav'].includes(type)) {
1740
+ return true;
1741
+ }
1742
+ // Check if it's a React component (likely block-level)
1743
+ if (typeof type === 'function' || (typeof type === 'object' && type !== null)) {
1744
+ return true;
1745
+ }
1746
+ }
1747
+ return false;
1748
+ });
1749
+ if (hasBlockLevelContent) {
1750
+ // Render block-level content without <p> wrapper
1751
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: parts });
1752
+ }
1733
1753
  return jsxRuntimeExports.jsx("p", { className: buildClassName('text-gray-700', textAlign), children: parts });
1734
1754
  }
1735
1755
  return jsxRuntimeExports.jsx("p", { className: buildClassName('text-gray-700', textAlign), children: content });
@@ -2307,6 +2327,121 @@ function convertImageToCloudflareVariant(url, options = {}) {
2307
2327
  }
2308
2328
  return url;
2309
2329
  }
2330
+ /**
2331
+ * Extract title from innerBlocks (finds first heading block)
2332
+ */
2333
+ function extractTitleFromInnerBlocks(block) {
2334
+ const innerBlocks = block.innerBlocks || [];
2335
+ // Recursively search for heading blocks
2336
+ for (const innerBlock of innerBlocks) {
2337
+ if (innerBlock.name === 'core/heading') {
2338
+ return getBlockTextContent(innerBlock);
2339
+ }
2340
+ // Recursively search nested blocks
2341
+ const nestedTitle = extractTitleFromInnerBlocks(innerBlock);
2342
+ if (nestedTitle)
2343
+ return nestedTitle;
2344
+ }
2345
+ return null;
2346
+ }
2347
+ /**
2348
+ * Extract subtitle/description from innerBlocks (finds first paragraph block)
2349
+ */
2350
+ function extractSubtitleFromInnerBlocks(block) {
2351
+ const innerBlocks = block.innerBlocks || [];
2352
+ // Recursively search for paragraph blocks
2353
+ for (const innerBlock of innerBlocks) {
2354
+ if (innerBlock.name === 'core/paragraph') {
2355
+ const text = getBlockTextContent(innerBlock);
2356
+ if (text && text.trim()) {
2357
+ return text;
2358
+ }
2359
+ }
2360
+ // Recursively search nested blocks
2361
+ const nestedSubtitle = extractSubtitleFromInnerBlocks(innerBlock);
2362
+ if (nestedSubtitle)
2363
+ return nestedSubtitle;
2364
+ }
2365
+ return null;
2366
+ }
2367
+ /**
2368
+ * Extract buttons from innerBlocks (finds buttons block and extracts button data)
2369
+ */
2370
+ function extractButtonsFromInnerBlocks(block) {
2371
+ const buttons = [];
2372
+ const innerBlocks = block.innerBlocks || [];
2373
+ // Find buttons block
2374
+ const findButtonsBlock = (blocks) => {
2375
+ for (const innerBlock of blocks) {
2376
+ if (innerBlock.name === 'core/buttons') {
2377
+ return innerBlock;
2378
+ }
2379
+ if (innerBlock.innerBlocks) {
2380
+ const found = findButtonsBlock(innerBlock.innerBlocks);
2381
+ if (found)
2382
+ return found;
2383
+ }
2384
+ }
2385
+ return null;
2386
+ };
2387
+ const buttonsBlock = findButtonsBlock(innerBlocks);
2388
+ if (!buttonsBlock || !buttonsBlock.innerBlocks) {
2389
+ return buttons;
2390
+ }
2391
+ // Extract button data from button blocks
2392
+ for (const buttonBlock of buttonsBlock.innerBlocks) {
2393
+ if (buttonBlock.name === 'core/button') {
2394
+ const attrs = buttonBlock.attributes || {};
2395
+ const url = attrs['url'];
2396
+ const text = attrs['text'] || getBlockTextContent(buttonBlock);
2397
+ // Try to extract from innerHTML if not in attributes
2398
+ if (!url && buttonBlock.innerHTML) {
2399
+ const linkMatch = buttonBlock.innerHTML.match(/<a[^>]+href=["']([^"']+)["'][^>]*>([^<]+)<\/a>/i);
2400
+ if (linkMatch) {
2401
+ const extractedUrl = linkMatch[1];
2402
+ const extractedText = linkMatch[2] || text;
2403
+ if (extractedUrl) {
2404
+ buttons.push({
2405
+ text: extractedText || 'Learn More',
2406
+ url: extractedUrl,
2407
+ isExternal: extractedUrl.startsWith('http://') || extractedUrl.startsWith('https://'),
2408
+ });
2409
+ }
2410
+ }
2411
+ }
2412
+ else if (url && text) {
2413
+ buttons.push({
2414
+ text,
2415
+ url,
2416
+ isExternal: url.startsWith('http://') || url.startsWith('https://'),
2417
+ });
2418
+ }
2419
+ }
2420
+ }
2421
+ return buttons;
2422
+ }
2423
+ /**
2424
+ * Extract video iframe HTML from innerBlocks (finds HTML block with iframe)
2425
+ */
2426
+ function extractVideoIframeFromInnerBlocks(block) {
2427
+ const innerBlocks = block.innerBlocks || [];
2428
+ // Recursively search for HTML blocks with iframe
2429
+ for (const innerBlock of innerBlocks) {
2430
+ if (innerBlock.name === 'core/html' && innerBlock.innerHTML) {
2431
+ // Check if innerHTML contains an iframe
2432
+ if (innerBlock.innerHTML.includes('<iframe')) {
2433
+ return innerBlock.innerHTML;
2434
+ }
2435
+ }
2436
+ // Recursively search nested blocks
2437
+ if (innerBlock.innerBlocks) {
2438
+ const nestedVideo = extractVideoIframeFromInnerBlocks(innerBlock);
2439
+ if (nestedVideo)
2440
+ return nestedVideo;
2441
+ }
2442
+ }
2443
+ return null;
2444
+ }
2310
2445
 
2311
2446
  /**
2312
2447
  * Convert image URL with optional Cloudflare variant transformation
@@ -2390,5 +2525,5 @@ const SectionWrapper = ({ children, background = 'light', spacing = 'medium', co
2390
2525
  return (jsxRuntimeExports.jsx("section", { className: buildClassName(backgroundClasses[finalBackground] || backgroundClasses.light, spacingClasses[finalSpacing] || spacingClasses.medium, containerClasses[finalContainer] || containerClasses.contained, className), children: children }));
2391
2526
  };
2392
2527
 
2393
- export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundImage, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractMediaPosition, extractMinHeight, extractOverlayColor, extractTextAlign, extractTextFromHTML, extractTitle, extractVerticalAlignment, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, isCloudflareImageUrl, matchesPattern, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
2528
+ export { SectionWrapper, WPContent, WPErrorBoundary, WPPage, buildClassName, convertImageToCloudflareVariant, convertImageUrl, convertImageUrls, createDefaultRegistry, createEnhancedRegistry, extractAlignment, extractBackgroundImage, extractButtonsFromInnerBlocks, extractContent, extractDimRatio, extractFontSize, extractHeadingLevel, extractImageAttributes, extractImageUrl, extractMediaPosition, extractMinHeight, extractOverlayColor, extractSubtitleFromInnerBlocks, extractTextAlign, extractTextFromHTML, extractTitle, extractTitleFromInnerBlocks, extractVerticalAlignment, extractVideoIframeFromInnerBlocks, findMatchingMapping, findShortcodes, getAlignmentClasses, getBlockTextContent, getCloudflareVariantUrl, getContainerClasses, getContentSpacingClasses, getFontSizeClasses, getImageAttributes, getImageUrl, getSectionSpacingClasses, getTextAlignClasses, isCloudflareImageUrl, matchesPattern, parseGutenbergBlocks, parseShortcodeAttrs, renderNodes, renderTextWithShortcodes };
2394
2529
  //# sourceMappingURL=index.esm.js.map