@marvalt/wparser 0.1.4 → 0.1.6
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 +331 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +84 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +319 -39
- package/dist/index.esm.js.map +1 -1
- package/dist/react/WPPage.d.ts.map +1 -1
- package/dist/registry/defaultRegistry.d.ts.map +1 -1
- package/dist/utils/cfImages.d.ts +18 -0
- package/dist/utils/cfImages.d.ts.map +1 -0
- package/dist/utils/contentExtractor.d.ts +29 -0
- package/dist/utils/contentExtractor.d.ts.map +1 -0
- package/dist/utils/styleMapper.d.ts +35 -0
- package/dist/utils/styleMapper.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1506,63 +1506,338 @@ function renderTextWithShortcodes(text, registry) {
|
|
|
1506
1506
|
return parts;
|
|
1507
1507
|
}
|
|
1508
1508
|
|
|
1509
|
+
/**
|
|
1510
|
+
* Content extraction utilities for WordPress blocks
|
|
1511
|
+
* Extracts text content from various block formats
|
|
1512
|
+
*/
|
|
1513
|
+
/**
|
|
1514
|
+
* Extract text content from a block's innerHTML by stripping HTML tags
|
|
1515
|
+
*/
|
|
1516
|
+
function extractTextFromHTML(html) {
|
|
1517
|
+
if (!html)
|
|
1518
|
+
return '';
|
|
1519
|
+
// Remove HTML tags and decode entities
|
|
1520
|
+
let text = html
|
|
1521
|
+
.replace(/<[^>]*>/g, '') // Remove HTML tags
|
|
1522
|
+
.replace(/ /g, ' ') // Replace with space
|
|
1523
|
+
.replace(/’/g, "'") // Replace apostrophe entity
|
|
1524
|
+
.replace(/“/g, '"') // Replace left double quote
|
|
1525
|
+
.replace(/”/g, '"') // Replace right double quote
|
|
1526
|
+
.replace(/…/g, '...') // Replace ellipsis
|
|
1527
|
+
.replace(/&/g, '&') // Replace &
|
|
1528
|
+
.replace(/</g, '<') // Replace <
|
|
1529
|
+
.replace(/>/g, '>') // Replace >
|
|
1530
|
+
.replace(/"/g, '"') // Replace "
|
|
1531
|
+
.replace(/–/g, '–') // Replace en dash
|
|
1532
|
+
.replace(/—/g, '—') // Replace em dash
|
|
1533
|
+
.trim();
|
|
1534
|
+
// Clean up extra whitespace
|
|
1535
|
+
text = text.replace(/\s+/g, ' ');
|
|
1536
|
+
return text;
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Extract text content from block attributes or innerHTML
|
|
1540
|
+
*/
|
|
1541
|
+
function getBlockTextContent(block) {
|
|
1542
|
+
const attrs = block.attributes || {};
|
|
1543
|
+
// Try various attribute keys
|
|
1544
|
+
const content = attrs['content'] || attrs['text'] || attrs['value'] || '';
|
|
1545
|
+
if (typeof content === 'string' && content.trim()) {
|
|
1546
|
+
return content.trim();
|
|
1547
|
+
}
|
|
1548
|
+
// Fall back to innerHTML
|
|
1549
|
+
if (block.innerHTML) {
|
|
1550
|
+
return extractTextFromHTML(block.innerHTML);
|
|
1551
|
+
}
|
|
1552
|
+
return '';
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Extract image URL from block attributes
|
|
1556
|
+
* Checks for Cloudflare URLs first, then falls back to regular URLs
|
|
1557
|
+
* Also extracts from innerHTML if needed
|
|
1558
|
+
*/
|
|
1559
|
+
function getImageUrl(block) {
|
|
1560
|
+
const attrs = block.attributes || {};
|
|
1561
|
+
// Check various possible URL attributes
|
|
1562
|
+
let url = attrs['url'] ||
|
|
1563
|
+
attrs['src'] ||
|
|
1564
|
+
attrs['imageUrl'] ||
|
|
1565
|
+
attrs['mediaUrl'] ||
|
|
1566
|
+
attrs['backgroundImage'];
|
|
1567
|
+
if (typeof url === 'string' && url.trim()) {
|
|
1568
|
+
return url.trim();
|
|
1569
|
+
}
|
|
1570
|
+
// Try to extract from innerHTML if it's an img tag
|
|
1571
|
+
if (block.innerHTML) {
|
|
1572
|
+
// Try img src first
|
|
1573
|
+
const imgMatch = block.innerHTML.match(/<img[^>]+src=["']([^"']+)["']/i);
|
|
1574
|
+
if (imgMatch && imgMatch[1]) {
|
|
1575
|
+
return imgMatch[1];
|
|
1576
|
+
}
|
|
1577
|
+
// Try background-image in style attribute
|
|
1578
|
+
const bgMatch = block.innerHTML.match(/background-image:\s*url\(["']?([^"')]+)["']?\)/i);
|
|
1579
|
+
if (bgMatch && bgMatch[1]) {
|
|
1580
|
+
return bgMatch[1];
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
return null;
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Extract image attributes (alt, width, height) from block
|
|
1587
|
+
*/
|
|
1588
|
+
function getImageAttributes(block) {
|
|
1589
|
+
const attrs = block.attributes || {};
|
|
1590
|
+
const url = getImageUrl(block);
|
|
1591
|
+
return {
|
|
1592
|
+
url,
|
|
1593
|
+
alt: attrs['alt'] || '',
|
|
1594
|
+
width: attrs['width'] ? Number(attrs['width']) : undefined,
|
|
1595
|
+
height: attrs['height'] ? Number(attrs['height']) : undefined,
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Style mapping utilities
|
|
1601
|
+
* Maps WordPress block attributes to Tailwind CSS classes
|
|
1602
|
+
*/
|
|
1603
|
+
/**
|
|
1604
|
+
* Map WordPress alignment to Tailwind classes
|
|
1605
|
+
*/
|
|
1606
|
+
function getAlignmentClasses(align) {
|
|
1607
|
+
if (!align)
|
|
1608
|
+
return '';
|
|
1609
|
+
switch (align) {
|
|
1610
|
+
case 'full':
|
|
1611
|
+
return 'w-full';
|
|
1612
|
+
case 'wide':
|
|
1613
|
+
return 'max-w-7xl mx-auto';
|
|
1614
|
+
case 'center':
|
|
1615
|
+
return 'mx-auto';
|
|
1616
|
+
case 'left':
|
|
1617
|
+
return 'mr-auto';
|
|
1618
|
+
case 'right':
|
|
1619
|
+
return 'ml-auto';
|
|
1620
|
+
default:
|
|
1621
|
+
return '';
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
/**
|
|
1625
|
+
* Map WordPress text alignment to Tailwind classes
|
|
1626
|
+
*/
|
|
1627
|
+
function getTextAlignClasses(textAlign) {
|
|
1628
|
+
if (!textAlign)
|
|
1629
|
+
return '';
|
|
1630
|
+
switch (textAlign) {
|
|
1631
|
+
case 'center':
|
|
1632
|
+
return 'text-center';
|
|
1633
|
+
case 'left':
|
|
1634
|
+
return 'text-left';
|
|
1635
|
+
case 'right':
|
|
1636
|
+
return 'text-right';
|
|
1637
|
+
default:
|
|
1638
|
+
return '';
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
/**
|
|
1642
|
+
* Map WordPress font size to Tailwind classes
|
|
1643
|
+
*/
|
|
1644
|
+
function getFontSizeClasses(fontSize) {
|
|
1645
|
+
if (!fontSize)
|
|
1646
|
+
return '';
|
|
1647
|
+
// Map WordPress font sizes to Tailwind
|
|
1648
|
+
const sizeMap = {
|
|
1649
|
+
'small': 'text-sm',
|
|
1650
|
+
'medium': 'text-base',
|
|
1651
|
+
'large': 'text-lg',
|
|
1652
|
+
'x-large': 'text-xl',
|
|
1653
|
+
'xx-large': 'text-3xl',
|
|
1654
|
+
'xxx-large': 'text-4xl',
|
|
1655
|
+
};
|
|
1656
|
+
return sizeMap[fontSize] || '';
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* Get container classes based on layout and alignment
|
|
1660
|
+
*/
|
|
1661
|
+
function getContainerClasses(align, layout) {
|
|
1662
|
+
const alignClass = getAlignmentClasses(align);
|
|
1663
|
+
// If layout is constrained, use container
|
|
1664
|
+
if (layout?.type === 'constrained') {
|
|
1665
|
+
return align === 'full' ? 'w-full' : 'container';
|
|
1666
|
+
}
|
|
1667
|
+
return alignClass || 'container';
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Get spacing classes for sections
|
|
1671
|
+
*/
|
|
1672
|
+
function getSectionSpacingClasses() {
|
|
1673
|
+
return 'py-16 md:py-24';
|
|
1674
|
+
}
|
|
1675
|
+
/**
|
|
1676
|
+
* Get content spacing classes
|
|
1677
|
+
*/
|
|
1678
|
+
function getContentSpacingClasses() {
|
|
1679
|
+
return 'space-y-6';
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Build className string from multiple class sources
|
|
1683
|
+
*/
|
|
1684
|
+
function buildClassName(...classes) {
|
|
1685
|
+
return classes
|
|
1686
|
+
.filter((cls) => Boolean(cls && cls.trim()))
|
|
1687
|
+
.join(' ')
|
|
1688
|
+
.trim();
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
/**
|
|
1692
|
+
* Cloudflare Images URL helpers for wparser package
|
|
1693
|
+
* Formats Cloudflare image URLs with variants for optimal performance
|
|
1694
|
+
*/
|
|
1695
|
+
/**
|
|
1696
|
+
* Check if a URL is a Cloudflare Images URL
|
|
1697
|
+
*/
|
|
1698
|
+
const isCloudflareImageUrl = (url) => {
|
|
1699
|
+
if (!url)
|
|
1700
|
+
return false;
|
|
1701
|
+
try {
|
|
1702
|
+
const u = new URL(url);
|
|
1703
|
+
return u.hostname.toLowerCase().includes('imagedelivery.net');
|
|
1704
|
+
}
|
|
1705
|
+
catch {
|
|
1706
|
+
return false;
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
/**
|
|
1710
|
+
* Append Cloudflare Images variant to the base URL if not already present.
|
|
1711
|
+
* Example output: https://imagedelivery.net/<account>/<id>/w=1024,h=600
|
|
1712
|
+
*/
|
|
1713
|
+
const getCloudflareVariantUrl = (url, options) => {
|
|
1714
|
+
if (!isCloudflareImageUrl(url))
|
|
1715
|
+
return url;
|
|
1716
|
+
// If a transform already exists, return as-is
|
|
1717
|
+
if (/\/w=\d+/.test(url) || /\/(public|thumbnail|banner|avatar)/.test(url)) {
|
|
1718
|
+
return url;
|
|
1719
|
+
}
|
|
1720
|
+
const { width, height } = options;
|
|
1721
|
+
const hasTrailingSlash = url.endsWith('/');
|
|
1722
|
+
const base = hasTrailingSlash ? url.slice(0, -1) : url;
|
|
1723
|
+
const variant = `w=${Math.max(1, Math.floor(width))}` + (height ? `,h=${Math.max(1, Math.floor(height))}` : '');
|
|
1724
|
+
return `${base}/${variant}`;
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1509
1727
|
const Paragraph = ({ block, context }) => {
|
|
1510
|
-
const content =
|
|
1728
|
+
const content = getBlockTextContent(block);
|
|
1729
|
+
const attrs = block.attributes || {};
|
|
1730
|
+
const textAlign = getTextAlignClasses(attrs['align']);
|
|
1511
1731
|
// Check if content contains shortcodes
|
|
1512
1732
|
const hasShortcodes = /\[(\w+)/.test(content);
|
|
1513
1733
|
if (hasShortcodes && context.registry.shortcodes) {
|
|
1514
1734
|
const parts = renderTextWithShortcodes(content, context.registry);
|
|
1515
|
-
return jsxRuntimeExports.jsx("p", { className:
|
|
1735
|
+
return jsxRuntimeExports.jsx("p", { className: buildClassName('text-gray-700', textAlign), children: parts });
|
|
1516
1736
|
}
|
|
1517
|
-
return jsxRuntimeExports.jsx("p", { className:
|
|
1737
|
+
return jsxRuntimeExports.jsx("p", { className: buildClassName('text-gray-700', textAlign), children: content });
|
|
1518
1738
|
};
|
|
1519
1739
|
const Heading = ({ block, children }) => {
|
|
1520
|
-
const
|
|
1521
|
-
const
|
|
1740
|
+
const attrs = block.attributes || {};
|
|
1741
|
+
const { level = 2 } = attrs;
|
|
1742
|
+
const content = getBlockTextContent(block);
|
|
1743
|
+
const textAlign = getTextAlignClasses(attrs['textAlign']);
|
|
1744
|
+
const fontSize = getFontSizeClasses(attrs['fontSize']);
|
|
1522
1745
|
const Tag = `h${Math.min(Math.max(Number(level) || 2, 1), 6)}`;
|
|
1523
|
-
|
|
1746
|
+
// Default heading sizes if fontSize not specified
|
|
1747
|
+
const sizeClass = fontSize || (level === 1 ? 'text-4xl' : level === 2 ? 'text-3xl' : level === 3 ? 'text-2xl' : 'text-xl');
|
|
1748
|
+
return (jsxRuntimeExports.jsx(Tag, { className: buildClassName('font-bold text-gray-900', sizeClass, textAlign), children: children ?? content }));
|
|
1524
1749
|
};
|
|
1525
1750
|
const Image = ({ block }) => {
|
|
1526
|
-
const
|
|
1527
|
-
if (!url)
|
|
1751
|
+
const imageAttrs = getImageAttributes(block);
|
|
1752
|
+
if (!imageAttrs.url)
|
|
1528
1753
|
return null;
|
|
1529
|
-
|
|
1754
|
+
// Use Cloudflare variant URL if it's a Cloudflare image
|
|
1755
|
+
let imageUrl = imageAttrs.url;
|
|
1756
|
+
if (isCloudflareImageUrl(imageUrl)) {
|
|
1757
|
+
const width = imageAttrs.width || 1024;
|
|
1758
|
+
const height = imageAttrs.height;
|
|
1759
|
+
imageUrl = getCloudflareVariantUrl(imageUrl, { width, height });
|
|
1760
|
+
}
|
|
1761
|
+
return (jsxRuntimeExports.jsx("img", { src: imageUrl, alt: imageAttrs.alt, width: imageAttrs.width, height: imageAttrs.height, className: "w-full h-auto object-cover rounded-lg", loading: "lazy" }));
|
|
1530
1762
|
};
|
|
1531
1763
|
const List = ({ block, children }) => {
|
|
1532
|
-
const
|
|
1764
|
+
const attrs = block.attributes || {};
|
|
1765
|
+
const { ordered } = attrs;
|
|
1533
1766
|
const Tag = ordered ? 'ol' : 'ul';
|
|
1534
|
-
return React.createElement(Tag, { className: 'list-disc pl-6 space-y-
|
|
1767
|
+
return React.createElement(Tag, { className: 'list-disc pl-6 space-y-2 text-gray-700' }, children);
|
|
1535
1768
|
};
|
|
1536
1769
|
const ListItem = ({ children }) => {
|
|
1537
|
-
return jsxRuntimeExports.jsx("li", { children: children });
|
|
1770
|
+
return jsxRuntimeExports.jsx("li", { className: "text-gray-700", children: children });
|
|
1538
1771
|
};
|
|
1539
|
-
const Group = ({ children }) => {
|
|
1540
|
-
|
|
1772
|
+
const Group = ({ block, children }) => {
|
|
1773
|
+
const attrs = block.attributes || {};
|
|
1774
|
+
const align = attrs['align'];
|
|
1775
|
+
const layout = attrs['layout'];
|
|
1776
|
+
// Determine if this is a section-level group (has alignment) or content-level
|
|
1777
|
+
const isSection = align === 'full' || align === 'wide';
|
|
1778
|
+
const containerClass = getContainerClasses(align, layout);
|
|
1779
|
+
const spacingClass = isSection ? getSectionSpacingClasses() : getContentSpacingClasses();
|
|
1780
|
+
return (jsxRuntimeExports.jsx("div", { className: buildClassName(containerClass, spacingClass), children: children }));
|
|
1541
1781
|
};
|
|
1542
|
-
const Columns = ({ children }) => {
|
|
1543
|
-
|
|
1782
|
+
const Columns = ({ block, children }) => {
|
|
1783
|
+
const attrs = block.attributes || {};
|
|
1784
|
+
const align = attrs['align'];
|
|
1785
|
+
const alignClass = getAlignmentClasses(align);
|
|
1786
|
+
return (jsxRuntimeExports.jsx("div", { className: buildClassName('grid grid-cols-1 md:grid-cols-2 gap-6 lg:gap-12', alignClass), children: children }));
|
|
1544
1787
|
};
|
|
1545
|
-
const Column = ({ children }) => {
|
|
1546
|
-
|
|
1788
|
+
const Column = ({ block, children }) => {
|
|
1789
|
+
const attrs = block.attributes || {};
|
|
1790
|
+
const width = attrs['width'];
|
|
1791
|
+
// Handle column width (e.g., "50%" becomes flex-basis)
|
|
1792
|
+
const style = width ? { flexBasis: width } : undefined;
|
|
1793
|
+
return (jsxRuntimeExports.jsx("div", { className: "space-y-4", style: style, children: children }));
|
|
1547
1794
|
};
|
|
1548
1795
|
const Separator = () => jsxRuntimeExports.jsx("hr", { className: "border-gray-200 my-8" });
|
|
1549
1796
|
const ButtonBlock = ({ block }) => {
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1797
|
+
const attrs = block.attributes || {};
|
|
1798
|
+
const url = attrs['url'];
|
|
1799
|
+
const text = attrs['text'];
|
|
1800
|
+
attrs['linkDestination'];
|
|
1801
|
+
if (!url && !text)
|
|
1552
1802
|
return null;
|
|
1553
|
-
|
|
1803
|
+
const buttonText = text || getBlockTextContent(block) || 'Learn more';
|
|
1804
|
+
// Handle internal vs external links
|
|
1805
|
+
const isExternal = url && (url.startsWith('http://') || url.startsWith('https://'));
|
|
1806
|
+
const linkProps = isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {};
|
|
1807
|
+
return (jsxRuntimeExports.jsx("a", { href: url || '#', className: "inline-flex items-center justify-center rounded-md bg-primary px-6 py-3 text-white font-medium hover:bg-primary/90 transition-colors", ...linkProps, children: buttonText }));
|
|
1554
1808
|
};
|
|
1555
1809
|
const Cover = ({ block, children }) => {
|
|
1556
1810
|
const attrs = block.attributes || {};
|
|
1557
|
-
const { url, backgroundImage, overlayColor, dimRatio = 0, align = 'full', minHeight, hasParallax, } = attrs;
|
|
1811
|
+
const { url, id, backgroundImage, overlayColor, dimRatio = 0, align = 'full', minHeight, minHeightUnit = 'vh', hasParallax, } = attrs;
|
|
1558
1812
|
// Get background image URL from various possible sources
|
|
1559
|
-
|
|
1813
|
+
let bgImageUrl = url || backgroundImage || (typeof backgroundImage === 'object' && backgroundImage?.url);
|
|
1814
|
+
// If not found in attributes, try to extract from innerHTML
|
|
1815
|
+
if (!bgImageUrl && block.innerHTML) {
|
|
1816
|
+
// Try to extract img src from innerHTML
|
|
1817
|
+
const imgMatch = block.innerHTML.match(/<img[^>]+src=["']([^"']+)["']/i);
|
|
1818
|
+
if (imgMatch && imgMatch[1]) {
|
|
1819
|
+
bgImageUrl = imgMatch[1];
|
|
1820
|
+
}
|
|
1821
|
+
// Try background-image in style attribute
|
|
1822
|
+
if (!bgImageUrl) {
|
|
1823
|
+
const bgMatch = block.innerHTML.match(/background-image:\s*url\(["']?([^"')]+)["']?\)/i);
|
|
1824
|
+
if (bgMatch && bgMatch[1]) {
|
|
1825
|
+
bgImageUrl = bgMatch[1];
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
// Convert to Cloudflare URL if it's a Cloudflare image, otherwise use as-is
|
|
1830
|
+
if (bgImageUrl && isCloudflareImageUrl(bgImageUrl)) {
|
|
1831
|
+
// Use full width for cover images
|
|
1832
|
+
bgImageUrl = getCloudflareVariantUrl(bgImageUrl, { width: 1920 });
|
|
1833
|
+
}
|
|
1560
1834
|
// Build alignment classes
|
|
1561
|
-
const alignClass = align
|
|
1835
|
+
const alignClass = getAlignmentClasses(align);
|
|
1562
1836
|
// Build style object
|
|
1563
1837
|
const style = {};
|
|
1564
1838
|
if (minHeight) {
|
|
1565
|
-
|
|
1839
|
+
const minHeightValue = typeof minHeight === 'number' ? minHeight : parseFloat(String(minHeight));
|
|
1840
|
+
style.minHeight = minHeightUnit === 'vh' ? `${minHeightValue}vh` : `${minHeightValue}px`;
|
|
1566
1841
|
}
|
|
1567
1842
|
if (bgImageUrl) {
|
|
1568
1843
|
style.backgroundImage = `url(${bgImageUrl})`;
|
|
@@ -1573,11 +1848,11 @@ const Cover = ({ block, children }) => {
|
|
|
1573
1848
|
}
|
|
1574
1849
|
}
|
|
1575
1850
|
// Calculate overlay opacity
|
|
1576
|
-
const overlayOpacity = dimRatio / 100;
|
|
1577
|
-
return (jsxRuntimeExports.jsxs("div", { className:
|
|
1578
|
-
backgroundColor: overlayColor || '#000000',
|
|
1851
|
+
const overlayOpacity = typeof dimRatio === 'number' ? dimRatio / 100 : 0;
|
|
1852
|
+
return (jsxRuntimeExports.jsxs("div", { className: buildClassName('relative w-full', alignClass), style: style, children: [overlayOpacity > 0 && (jsxRuntimeExports.jsx("span", { className: "absolute inset-0 z-0", style: {
|
|
1853
|
+
backgroundColor: overlayColor === 'contrast' ? '#000000' : (overlayColor || '#000000'),
|
|
1579
1854
|
opacity: overlayOpacity,
|
|
1580
|
-
}, "aria-hidden": "true" })), jsxRuntimeExports.jsx("div", { className:
|
|
1855
|
+
}, "aria-hidden": "true" })), jsxRuntimeExports.jsx("div", { className: buildClassName('relative z-10', align === 'full' ? 'w-full' : 'container mx-auto px-4'), children: children })] }));
|
|
1581
1856
|
};
|
|
1582
1857
|
const MediaText = ({ block, children, context }) => {
|
|
1583
1858
|
const attrs = block.attributes || {};
|
|
@@ -1594,7 +1869,7 @@ const MediaText = ({ block, children, context }) => {
|
|
|
1594
1869
|
// Content is all other children
|
|
1595
1870
|
const contentElements = childrenArray.filter((_, index) => index !== mediaBlockIndex);
|
|
1596
1871
|
// Build alignment classes
|
|
1597
|
-
const alignClass = align
|
|
1872
|
+
const alignClass = getAlignmentClasses(align) || 'max-w-7xl mx-auto';
|
|
1598
1873
|
// Vertical alignment classes
|
|
1599
1874
|
const verticalAlignClass = verticalAlignment === 'top' ? 'items-start' :
|
|
1600
1875
|
verticalAlignment === 'bottom' ? 'items-end' :
|
|
@@ -1603,7 +1878,7 @@ const MediaText = ({ block, children, context }) => {
|
|
|
1603
1878
|
const stackClass = 'flex-col md:flex-row';
|
|
1604
1879
|
// Media position determines order
|
|
1605
1880
|
const isMediaRight = mediaPosition === 'right';
|
|
1606
|
-
return (jsxRuntimeExports.jsx("div", { className:
|
|
1881
|
+
return (jsxRuntimeExports.jsx("div", { className: buildClassName(alignClass, 'px-4'), children: jsxRuntimeExports.jsxs("div", { className: buildClassName('flex', stackClass, verticalAlignClass, 'gap-6 lg:gap-12'), children: [jsxRuntimeExports.jsx("div", { className: buildClassName(isMediaRight ? 'order-2' : 'order-1', imageFill ? 'w-full md:w-1/2' : 'flex-shrink-0'), children: mediaElement || jsxRuntimeExports.jsx("div", { className: "bg-gray-200 h-64 rounded-lg" }) }), jsxRuntimeExports.jsx("div", { className: buildClassName(isMediaRight ? 'order-1' : 'order-2', imageFill ? 'w-full md:w-1/2' : 'flex-1', 'space-y-4'), children: contentElements.length > 0 ? contentElements : children })] }) }));
|
|
1607
1882
|
};
|
|
1608
1883
|
const Fallback = ({ block, children }) => {
|
|
1609
1884
|
// Minimal fallback; do not render innerHTML directly in v1 for safety
|
|
@@ -1621,7 +1896,15 @@ function createDefaultRegistry() {
|
|
|
1621
1896
|
'core/column': Column,
|
|
1622
1897
|
'core/separator': Separator,
|
|
1623
1898
|
'core/button': ButtonBlock,
|
|
1624
|
-
'core/buttons': ({ children }) =>
|
|
1899
|
+
'core/buttons': ({ block, children }) => {
|
|
1900
|
+
const attrs = block.attributes || {};
|
|
1901
|
+
const layout = attrs['layout'];
|
|
1902
|
+
const justifyContent = layout?.justifyContent || 'left';
|
|
1903
|
+
const justifyClass = justifyContent === 'center' ? 'justify-center' :
|
|
1904
|
+
justifyContent === 'right' ? 'justify-end' :
|
|
1905
|
+
'justify-start';
|
|
1906
|
+
return jsxRuntimeExports.jsx("div", { className: buildClassName('flex flex-wrap gap-3', justifyClass), children: children });
|
|
1907
|
+
},
|
|
1625
1908
|
'core/quote': ({ children }) => jsxRuntimeExports.jsx("blockquote", { className: "border-l-4 pl-4 italic", children: children }),
|
|
1626
1909
|
'core/code': ({ block }) => (jsxRuntimeExports.jsx("pre", { className: "bg-gray-100 p-3 rounded text-sm overflow-auto", children: jsxRuntimeExports.jsx("code", { children: getString(block) }) })),
|
|
1627
1910
|
'core/preformatted': ({ block }) => jsxRuntimeExports.jsx("pre", { children: getString(block) }),
|
|
@@ -1645,12 +1928,9 @@ function createDefaultRegistry() {
|
|
|
1645
1928
|
fallback: Fallback,
|
|
1646
1929
|
};
|
|
1647
1930
|
}
|
|
1931
|
+
// Legacy function for backward compatibility - use getBlockTextContent instead
|
|
1648
1932
|
function getString(block) {
|
|
1649
|
-
|
|
1650
|
-
const content = attrs['content'];
|
|
1651
|
-
const text = attrs['text'];
|
|
1652
|
-
const value = (typeof content === 'string' ? content : typeof text === 'string' ? text : block.innerHTML || '');
|
|
1653
|
-
return String(value);
|
|
1933
|
+
return getBlockTextContent(block);
|
|
1654
1934
|
}
|
|
1655
1935
|
|
|
1656
1936
|
const WPContent = ({ blocks, registry, className }) => {
|
|
@@ -1686,7 +1966,7 @@ const WPPage = ({ page, registry, className }) => {
|
|
|
1686
1966
|
}
|
|
1687
1967
|
const hasHeroShortcode = React.useMemo(() => detectHeroShortcode(page.blocks), [page.blocks]);
|
|
1688
1968
|
const featured = getFeaturedImage(page);
|
|
1689
|
-
return (jsxRuntimeExports.jsxs("article", { className: className, children: [!hasHeroShortcode && featured && (jsxRuntimeExports.jsx(HeroFromFeatured, { featured: featured, title: page.title?.rendered })), jsxRuntimeExports.
|
|
1969
|
+
return (jsxRuntimeExports.jsxs("article", { className: className, children: [!hasHeroShortcode && featured && (jsxRuntimeExports.jsx(HeroFromFeatured, { featured: featured, title: page.title?.rendered })), jsxRuntimeExports.jsx(WPContent, { blocks: page.blocks, registry: registry })] }));
|
|
1690
1970
|
};
|
|
1691
1971
|
function detectHeroShortcode(blocks) {
|
|
1692
1972
|
for (const block of blocks) {
|
|
@@ -1736,8 +2016,21 @@ class WPErrorBoundary extends React.Component {
|
|
|
1736
2016
|
exports.WPContent = WPContent;
|
|
1737
2017
|
exports.WPErrorBoundary = WPErrorBoundary;
|
|
1738
2018
|
exports.WPPage = WPPage;
|
|
2019
|
+
exports.buildClassName = buildClassName;
|
|
1739
2020
|
exports.createDefaultRegistry = createDefaultRegistry;
|
|
2021
|
+
exports.extractTextFromHTML = extractTextFromHTML;
|
|
1740
2022
|
exports.findShortcodes = findShortcodes;
|
|
2023
|
+
exports.getAlignmentClasses = getAlignmentClasses;
|
|
2024
|
+
exports.getBlockTextContent = getBlockTextContent;
|
|
2025
|
+
exports.getCloudflareVariantUrl = getCloudflareVariantUrl;
|
|
2026
|
+
exports.getContainerClasses = getContainerClasses;
|
|
2027
|
+
exports.getContentSpacingClasses = getContentSpacingClasses;
|
|
2028
|
+
exports.getFontSizeClasses = getFontSizeClasses;
|
|
2029
|
+
exports.getImageAttributes = getImageAttributes;
|
|
2030
|
+
exports.getImageUrl = getImageUrl;
|
|
2031
|
+
exports.getSectionSpacingClasses = getSectionSpacingClasses;
|
|
2032
|
+
exports.getTextAlignClasses = getTextAlignClasses;
|
|
2033
|
+
exports.isCloudflareImageUrl = isCloudflareImageUrl;
|
|
1741
2034
|
exports.parseGutenbergBlocks = parseGutenbergBlocks;
|
|
1742
2035
|
exports.parseShortcodeAttrs = parseShortcodeAttrs;
|
|
1743
2036
|
exports.renderNodes = renderNodes;
|