{
  "version": 3,
  "sources": ["../../src/utils/waveform-utils.js"],
  "sourcesContent": ["/**\n * Shared utilities for waveform audio player functionality.\n * Used by both the WaveformPlayer component (editor) and view.js (frontend).\n */\n\n/**\n * External dependencies\n */\nimport { colord } from 'colord';\nimport WaveformPlayerLib from '@arraypress/waveform-player';\n\n/**\n * Configuration constants.\n * Note: DEFAULT_WAVEFORM_HEIGHT should match $waveform-player-height in style.scss.\n */\nconst DEFAULT_WAVEFORM_HEIGHT = 100;\n\n/**\n * Get computed style for an element, using ownerDocument for iframe compatibility.\n *\n * @param {Element} element - The element to get styles from.\n * @return {CSSStyleDeclaration} The computed style.\n */\nfunction getComputedStyle( element ) {\n\treturn element.ownerDocument.defaultView.getComputedStyle( element );\n}\n\n/**\n * Get all colors needed for the waveform player based on the element's styles.\n *\n * @param {Element} element - The element to derive colors from.\n * @return {Object} Object containing textColor, waveformColor, progressColor.\n */\nexport function getWaveformColors( element ) {\n\tconst textColor = getComputedStyle( element ).color;\n\tconst waveformColor = colord( textColor ).alpha( 0.3 ).toRgbString();\n\tconst progressColor = colord( textColor ).alpha( 0.6 ).toRgbString();\n\n\treturn { textColor, waveformColor, progressColor };\n}\n\n/**\n * Create a waveform container element with the specified attributes.\n *\n * @param {Object} options               - The options for the container.\n * @param {string} options.url           - The audio URL.\n * @param {string} options.title         - The track title.\n * @param {string} options.artist        - The track artist.\n * @param {string} options.artwork       - The album artwork URL.\n * @param {string} options.waveformColor - The waveform bar color.\n * @param {string} options.progressColor - The progress indicator color.\n * @param {string} options.buttonColor   - The play button color.\n * @param {number} options.height        - The waveform height in pixels.\n * @return {Element} The configured container element.\n */\nexport function createWaveformContainer( {\n\turl,\n\ttitle,\n\tartist,\n\tartwork,\n\twaveformColor,\n\tprogressColor,\n\tbuttonColor,\n\theight = DEFAULT_WAVEFORM_HEIGHT,\n} ) {\n\tconst container = document.createElement( 'div' );\n\tcontainer.setAttribute( 'data-waveform-player', '' );\n\tcontainer.setAttribute( 'data-url', url );\n\tcontainer.setAttribute( 'data-height', String( height ) );\n\tcontainer.setAttribute( 'data-waveform-style', 'bars' );\n\tcontainer.setAttribute( 'data-waveform-color', waveformColor );\n\tcontainer.setAttribute( 'data-progress-color', progressColor );\n\tcontainer.setAttribute( 'data-button-color', buttonColor );\n\tcontainer.setAttribute( 'data-text-color', buttonColor );\n\tcontainer.setAttribute( 'data-text-secondary-color', buttonColor );\n\tif ( title ) {\n\t\tcontainer.setAttribute( 'data-title', title );\n\t}\n\tif ( artist ) {\n\t\tcontainer.setAttribute( 'data-subtitle', artist );\n\t}\n\tif ( artwork ) {\n\t\tcontainer.setAttribute( 'data-artwork', artwork );\n\t}\n\treturn container;\n}\n\n/**\n * Apply contrasting color to SVG icon paths for visibility.\n * The icons should contrast with the button background (which uses textColor).\n *\n * @param {Element} container   - The waveform container element.\n * @param {string}  buttonColor - The button background color (textColor).\n */\nexport function styleSvgIcons( container, buttonColor ) {\n\t// Compute a contrasting color for the icons based on button brightness.\n\tconst isButtonDark = colord( buttonColor ).isDark();\n\tconst iconColor = isButtonDark ? '#ffffff' : '#000000';\n\n\tconst svgPaths = container.querySelectorAll( 'svg path' );\n\tsvgPaths.forEach( ( path ) => {\n\t\tpath.style.fill = iconColor;\n\t} );\n}\n\n/**\n * Set up play button accessibility: aria-label that toggles on play/pause.\n *\n * @param {Element} container    - The waveform container element.\n * @param {Object}  labels       - Button labels.\n * @param {string}  labels.play  - Label for the play state.\n * @param {string}  labels.pause - Label for the pause state.\n */\nexport function setupPlayButtonAccessibility(\n\tcontainer,\n\t{ play: playLabel = 'Play', pause: pauseLabel = 'Pause' } = {}\n) {\n\tconst playBtn = container.querySelector( '.waveform-btn' );\n\tif ( ! playBtn ) {\n\t\treturn;\n\t}\n\n\tplayBtn.setAttribute( 'aria-label', playLabel );\n\n\tconst onPlay = () => playBtn.setAttribute( 'aria-label', pauseLabel );\n\tconst onPause = () => playBtn.setAttribute( 'aria-label', playLabel );\n\n\tcontainer.addEventListener( 'waveformplayer:play', onPlay );\n\tcontainer.addEventListener( 'waveformplayer:pause', onPause );\n\tcontainer.addEventListener( 'waveformplayer:ended', onPause );\n\n\treturn () => {\n\t\tcontainer.removeEventListener( 'waveformplayer:play', onPlay );\n\t\tcontainer.removeEventListener( 'waveformplayer:pause', onPause );\n\t\tcontainer.removeEventListener( 'waveformplayer:ended', onPause );\n\t};\n}\n\n/**\n * Log play errors, filtering out expected AbortError.\n *\n * @param {Error} error - The error from play().\n */\nexport function logPlayError( error ) {\n\t// The browser throws AbortError when a play() promise is interrupted\n\t// by a subsequent pause() or a new audio source load (track change).\n\t// This is normal during rapid user interaction and safe to ignore.\n\tif ( error.name === 'AbortError' ) {\n\t\treturn;\n\t}\n\t// eslint-disable-next-line no-console\n\tconsole.error( 'Playlist play error:', error );\n}\n\n/**\n * Initialize a WaveformPlayer instance on an element.\n *\n * This is the shared core logic used by both the React component (editor)\n * and the Interactivity API (frontend).\n *\n * @param {Element}  element          - The container element (must be in DOM).\n * @param {Object}   options          - Configuration options.\n * @param {string}   options.src      - The audio file URL.\n * @param {string}   options.title    - The track title.\n * @param {string}   options.artist   - The artist name.\n * @param {string}   options.image    - The artwork image URL.\n * @param {boolean}  options.autoPlay - Whether to auto-play when ready.\n * @param {Function} options.onEnded  - Callback when track ends.\n * @param {Object}   options.labels   - Translated button labels.\n * @return {Object} Object with instance, container, and destroy function.\n */\nexport function initWaveformPlayer(\n\telement,\n\t{ src, title, artist, image, autoPlay, onEnded, labels }\n) {\n\t// Get colors from computed styles.\n\tconst { textColor, waveformColor, progressColor } =\n\t\tgetWaveformColors( element );\n\n\t// Create the waveform container.\n\tconst container = createWaveformContainer( {\n\t\turl: src,\n\t\ttitle,\n\t\tartist,\n\t\tartwork: image,\n\t\twaveformColor,\n\t\tprogressColor,\n\t\tbuttonColor: textColor,\n\t} );\n\telement.appendChild( container );\n\n\t// Initialize the WaveformPlayer library.\n\tconst instance = new WaveformPlayerLib( container );\n\n\t// Set up event handlers.\n\tlet cleanupAccessibility;\n\tconst handlers = {\n\t\tready: () => {\n\t\t\tstyleSvgIcons( container, textColor );\n\t\t\tcleanupAccessibility = setupPlayButtonAccessibility(\n\t\t\t\tcontainer,\n\t\t\t\tlabels\n\t\t\t);\n\t\t\tif ( autoPlay ) {\n\t\t\t\tinstance.play()?.catch( logPlayError );\n\t\t\t}\n\t\t},\n\t\tended: () => onEnded?.(),\n\t};\n\n\tcontainer.addEventListener( 'waveformplayer:ready', handlers.ready );\n\tcontainer.addEventListener( 'waveformplayer:ended', handlers.ended );\n\n\t// Return instance, container, and cleanup function.\n\treturn {\n\t\tinstance,\n\t\tcontainer,\n\t\tdestroy: () => {\n\t\t\tcleanupAccessibility?.();\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ready',\n\t\t\t\thandlers.ready\n\t\t\t);\n\t\t\tcontainer.removeEventListener(\n\t\t\t\t'waveformplayer:ended',\n\t\t\t\thandlers.ended\n\t\t\t);\n\t\t\tinstance.destroy();\n\t\t\tcontainer.remove();\n\t\t},\n\t};\n}\n"],
  "mappings": "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",
  "names": ["WaveformPlayerLib"]
}
