11import { EventHandler } from "./bootstrap-helper" ;
22
3+ /**
4+ * Initializes the card body elements by applying text truncation if the content exceeds
5+ * a specified height based on the CSS line-clamp and line-height properties. Adds
6+ * accessible text for truncated content.
7+ *
8+ * @return {void } This function does not return any value.
9+ */
310function initCardBodies ( ) {
411
512 const cardBodies = document . querySelectorAll ( '.card-body' ) ;
613 cardBodies . forEach ( ( cardBody , index ) => {
714 const paragraph = cardBody . querySelector ( 'div p' ) ;
815 const originalText = paragraph . textContent ;
916 const style = window . getComputedStyle ( cardBody ) ;
17+
18+ // Get the number of lines allowed (line clamp), usually set via CSS like -webkit-line-clamp
1019 const lineClamp = parseInt ( style . webkitLineClamp || style . lineClamp ) ;
20+
21+ // Get the line height and font size from the styles
1122 const lineHeight = parseFloat ( style . lineHeight ) ;
1223 const fontSize = parseFloat ( style . fontSize ) ;
24+
25+ // Calculate the actual line height. If lineHeight is not a number, estimate using fontSize
1326 const actualLineHeight = isNaN ( lineHeight ) ? parseFloat ( style . lineHeight ) * fontSize : lineHeight ;
27+
28+ // Calculate the maximum height allowed for the paragraph (lines × line height)
1429 const maxHeight = lineClamp * actualLineHeight ;
1530
31+ // Check if the paragraph exceeds the maximum allowed height
1632 if ( paragraph . offsetHeight >= maxHeight ) {
1733 let visibleText = '' ;
1834 const words = originalText . split ( ' ' ) ;
1935 let visibleWordCount = 0 ;
2036 let tempText = '' ;
37+
38+ // Add words one by one until the text height exceeds the max allowed height
2139 while ( visibleWordCount < words . length && getTextHeight ( tempText + ( tempText ? ' ' : '' ) + words [ visibleWordCount ] , paragraph ) <= maxHeight ) {
2240 tempText += ( tempText ? ' ' : '' ) + words [ visibleWordCount ] ;
2341 visibleWordCount ++ ;
2442 }
2543 visibleText = tempText + '...' ;
2644
45+ // Create a new hidden element to store the truncated text
2746 const visibleTextElementId = `visible-text-${ Math . random ( ) . toString ( 36 ) . substring ( 7 ) } ` ;
2847 const visibleTextElement = document . createElement ( 'div' ) ;
2948 visibleTextElement . id = visibleTextElementId ;
@@ -32,16 +51,27 @@ function initCardBodies() {
3251 visibleTextElement . style . top = '0' ;
3352 visibleTextElement . style . zIndex = '-1' ;
3453
54+ // Add the hidden element to the DOM
3555 cardBody . appendChild ( visibleTextElement ) ;
3656
3757 paragraph . setAttribute ( 'aria-describedby' , visibleTextElementId ) ;
58+
59+ // Hide the original paragraph from screen readers
3860 paragraph . setAttribute ( 'aria-hidden' , 'true' ) ;
3961 }
4062 } ) ;
4163
4264
43- } ;
65+ }
4466
67+ /**
68+ * Calculates the rendered height of a given text when styled and constrained
69+ * within the dimensions and styles of the specified HTML element.
70+ *
71+ * @param {string } text - The text content whose height is to be measured.
72+ * @param {HTMLElement } element - The element used to derive styling and width constraints.
73+ * @return {number } The height in pixels of the rendered text.
74+ */
4575function getTextHeight ( text , element ) {
4676 const tempElement = document . createElement ( element . tagName ) ;
4777 tempElement . style . font = window . getComputedStyle ( element ) . font ;
0 commit comments