@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 +139 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +136 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/registry/defaultRegistry.d.ts.map +1 -1
- package/dist/utils/blockExtractors.d.ts +20 -0
- package/dist/utils/blockExtractors.d.ts.map +1 -1
- package/package.json +1 -1
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;
|