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