|
1 | 1 | 'use client'; |
2 | 2 |
|
3 | | -import {ReactNode, useCallback, useEffect, useRef, useState} from 'react'; |
4 | | -import {ChevronDownIcon, ChevronRightIcon} from '@radix-ui/react-icons'; |
| 3 | +import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; |
| 4 | +import { ChevronDownIcon, ChevronRightIcon } from '@radix-ui/react-icons'; |
5 | 5 | import * as Sentry from '@sentry/nextjs'; |
6 | 6 |
|
7 | | -import {usePlausibleEvent} from 'sentry-docs/hooks/usePlausibleEvent'; |
| 7 | +import { usePlausibleEvent } from 'sentry-docs/hooks/usePlausibleEvent'; |
8 | 8 |
|
9 | 9 | // explicitly not usig CSS modules here |
10 | 10 | // because there's some prerendered content that depends on these exact class names |
@@ -41,12 +41,12 @@ export function Expandable({ |
41 | 41 | const [isExpanded, setIsExpanded] = useState(false); |
42 | 42 | const [copied, setCopied] = useState(false); |
43 | 43 | const contentRef = useRef<HTMLDivElement>(null); |
44 | | - const {emit} = usePlausibleEvent(); |
| 44 | + const { emit } = usePlausibleEvent(); |
45 | 45 |
|
46 | 46 | // Ensure we scroll to the element if the URL hash matches |
47 | 47 | useEffect(() => { |
48 | 48 | if (!id) { |
49 | | - return () => {}; |
| 49 | + return () => { }; |
50 | 50 | } |
51 | 51 |
|
52 | 52 | if (window.location.hash === `#${id}`) { |
@@ -78,24 +78,36 @@ export function Expandable({ |
78 | 78 | return; |
79 | 79 | } |
80 | 80 |
|
81 | | - emit('Copy Expandable Content', {props: {page: window.location.pathname, title}}); |
| 81 | + emit('Copy Expandable Content', { props: { page: window.location.pathname, title } }); |
82 | 82 |
|
83 | | - // Attempt to get text from markdown code blocks if they exist |
84 | | - const codeBlocks = contentRef.current.querySelectorAll('code'); |
| 83 | + // First, try to get text from main code blocks (those inside pre elements) |
| 84 | + const preCodeBlocks = contentRef.current.querySelectorAll('pre code'); |
85 | 85 | let contentToCopy = ''; |
86 | 86 |
|
87 | | - if (codeBlocks.length > 0) { |
88 | | - // If there are code blocks, concatenate their text content |
89 | | - codeBlocks.forEach(block => { |
90 | | - // Exclude code elements within other code elements (e.g. inline code in a block) |
91 | | - if (!block.closest('code')?.parentElement?.closest('code')) { |
92 | | - contentToCopy += (block.textContent || '') + '\n'; |
93 | | - } |
| 87 | + if (preCodeBlocks.length > 0) { |
| 88 | + // If there are pre code blocks, concatenate their text content |
| 89 | + preCodeBlocks.forEach(block => { |
| 90 | + contentToCopy += (block.textContent || '') + '\n'; |
94 | 91 | }); |
95 | 92 | contentToCopy = contentToCopy.trim(); |
| 93 | + } else { |
| 94 | + // Fallback: Look for large standalone code blocks (not inline code) |
| 95 | + const allCodeBlocks = contentRef.current.querySelectorAll('code'); |
| 96 | + const largeCodeBlocks = Array.from(allCodeBlocks).filter((block: Element) => { |
| 97 | + // Skip inline code (usually short and inside paragraphs) |
| 98 | + const isInlineCode = block.closest('p') !== null && (block.textContent?.length || 0) < 100; |
| 99 | + return !isInlineCode; |
| 100 | + }); |
| 101 | + |
| 102 | + if (largeCodeBlocks.length > 0) { |
| 103 | + largeCodeBlocks.forEach((block: Element) => { |
| 104 | + contentToCopy += (block.textContent || '') + '\n'; |
| 105 | + }); |
| 106 | + contentToCopy = contentToCopy.trim(); |
| 107 | + } |
96 | 108 | } |
97 | 109 |
|
98 | | - // Fallback to the whole content if no code blocks or if they are empty |
| 110 | + // Final fallback to the whole content if no code blocks or if they are empty |
99 | 111 | if (!contentToCopy && contentRef.current.textContent) { |
100 | 112 | contentToCopy = contentRef.current.textContent.trim(); |
101 | 113 | } |
@@ -123,7 +135,7 @@ export function Expandable({ |
123 | 135 | setIsExpanded(newVal); |
124 | 136 |
|
125 | 137 | if (newVal) { |
126 | | - emit('Open Expandable', {props: {page: window.location.pathname, title}}); |
| 138 | + emit('Open Expandable', { props: { page: window.location.pathname, title } }); |
127 | 139 | } |
128 | 140 |
|
129 | 141 | if (id) { |
|
0 commit comments