From 09b69f02ba49ed4437d1b3b03f53b7478f3c8611 Mon Sep 17 00:00:00 2001 From: iconoclasthero Date: Fri, 22 May 2026 17:16:28 -0400 Subject: [PATCH 1/2] Refactor Audible button functionality and event handling for optional iframe Audible view For match view: Adds option for defaulting audible opening for potential expansion to control panel. Toggles opening style with control/cmd click. Helpers could be expanded for e.g., goodreads --- ABSidekick.user.js | 110 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 20 deletions(-) diff --git a/ABSidekick.user.js b/ABSidekick.user.js index 2f81969..bafb80d 100644 --- a/ABSidekick.user.js +++ b/ABSidekick.user.js @@ -302,7 +302,7 @@ async function itemPageInjector(itemPage) { SETTINGS.itemButtonGlass ? goodreadsButton.classList.add('itemButtonGlass') : null goodreadsButton.title = 'Search Goodreads for this title' goodreadsButton.addEventListener('click', function(event) { - // Open the Audible page using the available ASIN + // Open the Goodreads page using the available title let goodreadsURL = SETTINGS.goodreadsTemplate.replace(/%title%/, encodeURI(templateVariables.title)) window.open(goodreadsURL, '_blank') @@ -325,7 +325,6 @@ async function itemPageInjector(itemPage) { let asinURL = SETTINGS.audibleTemplate.replace(/%asin%/, metadata.media.metadata.asin) window.open(asinURL, '_blank') - }) itemPage.querySelector('#buttonsRow > div:last-child').insertAdjacentElement('beforebegin', audibleButton) @@ -570,11 +569,14 @@ async function matchTabInjector() { // Audible Button let asinButton = document.createElement('button') + asinButton.innerText = 'Audible' asinButton.title = 'Open the Audible page of this match result\n\nℹ️ Only works if the match result has an ASIN' asinButton.classList.add('asinSearch', 'resultButton') - asinButton.addEventListener('mouseup', function(event) { - event.button == 0 ? audibleLookup(this) : null + + // single clean entry point + asinButton.addEventListener('click', function (event) { + audibleLookup(this, event) }) // Create and populate the element that will contain the ABSidekick buttons @@ -986,30 +988,98 @@ async function saveResult(matchButton, additionalTags = false) { } -async function audibleLookup(asinButton) { - // The 'Audible' lookup button of the MatchTab was clicked +async function audibleLookup(asinButton, event) { - // The floating Edit panel let editPanel = document.getElementById('editPanel') - // Click the book item, which will load the form data - asinButton.closest('div.resultContainer').querySelector('div.resultProcessed').click() + asinButton + .closest('div.resultContainer') + .querySelector('div.resultProcessed') + .click() - // Wait until the submit button is available, indicating the form is available, then get the ASIN - let submitButton = await waitForElement('button.bg-success[type="submit"]', editPanel.querySelector('#match-wrapper')) + await waitForElement( + 'button.bg-success[type="submit"]', + editPanel.querySelector('#match-wrapper') + ) - let asinURL - try { - let asinValue = editPanel.querySelector('#match-wrapper input[placeholder="ASIN"]').value - asinURL = SETTINGS.audibleTemplate.replace(/%asin%/, asinValue) - } catch(error) {} + let asinValue = editPanel + .querySelector('#match-wrapper input[placeholder="ASIN"]') + ?.value + + let backArrowElement = editPanel + .querySelector('div.cursor-pointer:has(> span.material-symbols') + + backArrowElement?.click() + + if (!asinValue) { + asinButton.innerText = 'No ASIN' + return + } + + let asinURL = SETTINGS.audibleTemplate.replace(/%asin%/, asinValue) - // Click the back arrow to return to match results - let backArrowElement = editPanel.querySelector('div.cursor-pointer:has(> span.material-symbols') - backArrowElement.click() + handleAudibleOpen(asinURL, event) +} + +// Flag `audibleInABS` for default Audible opening in new tab vs. frame in ABS window. +// Inetegrate into contol panel option? +function handleAudibleOpen(asinURL, event = {}, audibleInABS = false) { + + let invert = event.ctrlKey || event.metaKey + let useFrame = invert ? !audibleInABS : audibleInABS - asinURL ? window.open(asinURL, '_blank') : asinButton.innerText = 'No ASIN' + if (useFrame) { + openAudibleFrame(asinURL) + } else { + window.open(asinURL, '_blank') + } +} + + +function openAudibleFrame(url) { + let frame = document.getElementById('abs-audible-frame') + + if (!frame) { + frame = document.createElement('iframe') + frame.id = 'abs-audible-frame' + + frame.style.position = 'fixed' + frame.style.top = '0' + frame.style.left = '0' + frame.style.width = '100vw' + frame.style.height = '100vh' + frame.style.zIndex = '999999' + frame.style.border = 'none' + frame.style.background = 'white' + + document.body.appendChild(frame) + + // ADD EXIT BUTTON + const closeBtn = document.createElement('button') + closeBtn.style.display = 'flex' + closeBtn.style.alignItems = 'center' + closeBtn.style.gap = '8px' + + closeBtn.innerHTML = ` + RETURN TO ABS + ` + closeBtn.style.position = 'fixed' + closeBtn.style.top = '10px' + closeBtn.style.left = '50%' + closeBtn.style.transform = 'translateX(-50%)' + closeBtn.style.zIndex = '1000000' + closeBtn.style.padding = '6px 10px' + + closeBtn.onclick = () => { + frame.remove() + closeBtn.remove() + } + + document.body.appendChild(closeBtn) + } + frame.src = url } From 4a45fb49aed7236aee8a20011053609cec51b9f1 Mon Sep 17 00:00:00 2001 From: iconoclasthero Date: Fri, 22 May 2026 17:49:21 -0400 Subject: [PATCH 2/2] restored comments found missing in diff --- ABSidekick.user.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ABSidekick.user.js b/ABSidekick.user.js index bafb80d..0af1b4c 100644 --- a/ABSidekick.user.js +++ b/ABSidekick.user.js @@ -989,14 +989,18 @@ async function saveResult(matchButton, additionalTags = false) { async function audibleLookup(asinButton, event) { + // The 'Audible' lookup button of the MatchTab was clicked + // The floating Edit panel let editPanel = document.getElementById('editPanel') + // Click the book item, which will load the form data asinButton .closest('div.resultContainer') .querySelector('div.resultProcessed') .click() + // Wait until the submit button is available, indicating the form is available, then get the ASIN await waitForElement( 'button.bg-success[type="submit"]', editPanel.querySelector('#match-wrapper') @@ -1006,6 +1010,7 @@ async function audibleLookup(asinButton, event) { .querySelector('#match-wrapper input[placeholder="ASIN"]') ?.value + // Click the back arrow to return to match results let backArrowElement = editPanel .querySelector('div.cursor-pointer:has(> span.material-symbols') @@ -1021,7 +1026,7 @@ async function audibleLookup(asinButton, event) { handleAudibleOpen(asinURL, event) } -// Flag `audibleInABS` for default Audible opening in new tab vs. frame in ABS window. +// Flag `audibleInABS` for default Audible opening in new tab vs. iframe in ABS window. // Inetegrate into contol panel option? function handleAudibleOpen(asinURL, event = {}, audibleInABS = false) {