Greasy Fork

Bookracy Redirect

Adds a button to book-related websites to search the current book title on Bookracy.ru

// ==UserScript==
// @name         Bookracy Redirect
// @namespace    Violentmonkey Scripts
// @version      0.1
// @description  Adds a button to book-related websites to search the current book title on Bookracy.ru
// @author       Gemini
// @match        https://thegreatestbooks.org/*
// @match        https://www.goodreads.com/*
// @match        https://www.amazon.com/*
// @match        https://www.amazon.fr/*
// @match        https://www.amazon.de/*
// @match        https://www.amazon.co.uk/*
// @match        https://www.amazon.it/*
// @match        https://www.amazon.*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Attempts to extract the book title from the current page based on its hostname.
     * It uses specific selectors for known sites and falls back to general H1 tags or document title.
     * @returns {string} The extracted book title, or an empty string if not found.
     */
    function getBookTitle() {
        let title = '';
        const hostname = window.location.hostname;

        // --- Specific rules for different websites ---
        if (hostname.includes('goodreads.com')) {
            // Goodreads: Book title is usually in an h1 with id 'bookTitle'
            const el = document.getElementById('bookTitle');
            if (el) {
                title = el.innerText.trim();
            }
        } else if (hostname.includes('amazon.')) {
            // Amazon (all domains): Book title is usually in an h1 with id 'productTitle' or 'bookTitle'
            const el = document.getElementById('productTitle') || document.getElementById('bookTitle');
            if (el) {
                title = el.innerText.trim();
            }
        } else if (
            hostname.includes('thegreatestbooks.org')
            // Removed: hostname.includes('fivebooks.com')
            // Removed: hostname.includes('mostrecommendedbooks.com')
            // Removed: hostname.includes('redditreads.com')
        ) {
            // General approach for other book list/review sites:
            // Try common header tags for the main title on the page.
            // Prioritize a specific class if known, then general h1.
            let el = document.querySelector('h1.book-title') || document.querySelector('h1');
            if (el) {
                title = el.innerText.trim();
            }
            // Fallback to title tag if h1 not found or empty
            if (!title && document.title) {
                title = document.title;
            }
        }

        // --- General Fallback and Cleaning ---
        // If no specific rule matched or element found, use the document title as a last resort.
        if (!title && document.title) {
            title = document.title;
        }

        // Clean up common suffixes/prefixes often found in titles (e.g., from browser tabs or Goodreads)
        title = title
            .replace(/ - Wikipedia$/, '') // Remove Wikipedia suffix
            .replace(/ \| Goodreads$/, '') // Remove Goodreads suffix
            .replace(/ \| Five Books$/, '') // Remove Five Books suffix
            .replace(/\(Paperback\)/, '') // Remove (Paperback)
            .replace(/\(Hardcover\)/, '') // Remove (Hardcover)
            .replace(/\(Kindle\)/, '') // Remove (Kindle)
            .replace(/ by [A-Za-z\s]+$/, '') // Remove " by Author Name" at the end
            .replace(/ Series$/, '') // Remove " Series"
            .trim(); // Trim any leading/trailing whitespace

        return title;
    }

    /**
     * Creates and appends the "Search on Bookracy" button to the page.
     * The button will be positioned at the bottom right corner of the viewport.
     */
    function createBookracyButton() {
        const bookTitle = getBookTitle();

        // Only create the button if a book title was successfully extracted
        if (!bookTitle) {
            console.log("Book title not found on this page, skipping Bookracy button creation.");
            return;
        }

        const button = document.createElement('button');
        button.innerText = 'Search on Bookracy';

        // Apply basic inline styles for visibility and consistent appearance
        button.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            background-color: #4CAF50; /* Green */
            color: white;
            padding: 10px 18px; /* Slightly more padding for touch targets */
            border: none;
            border-radius: 8px; /* Rounded corners */
            cursor: pointer;
            font-family: 'Inter', sans-serif; /* Use Inter font for consistency */
            font-size: 16px;
            font-weight: 500;
            z-index: 10000; /* Ensure button is above other content */
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); /* Stronger shadow for depth */
            transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
            outline: none; /* Remove focus outline */
        `;

        // Add hover effects for a more interactive feel
        button.onmouseover = function() {
            this.style.backgroundColor = '#45a049'; // Darker green on hover
            this.style.transform = 'scale(1.05)'; // Slightly enlarge on hover
            this.style.boxShadow = '0 6px 15px rgba(0, 0, 0, 0.3)'; // Enhanced shadow
        };

        // Revert styles on mouse out
        button.onmouseout = function() {
            this.style.backgroundColor = '#4CAF50';
            this.style.transform = 'scale(1)';
            this.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.25)';
        };

        // Handle button click event
        button.onclick = function() {
            // Encode the book title to ensure it's a valid URL parameter
            const encodedTitle = encodeURIComponent(bookTitle);
            // Construct the Bookracy URL and open it in a new tab
            window.open(`https://bookracy.ru/?q=${encodedTitle}`, '_blank');
        };

        // Append the button to the document body
        document.body.appendChild(button);
    }

    // Ensure the script runs after the DOM is fully loaded.
    // This prevents errors if elements are not yet available.
    if (document.readyState === 'loading') {
        window.addEventListener('DOMContentLoaded', createBookracyButton);
    } else {
        // If the DOM is already loaded (e.g., script injected late), run immediately.
        createBookracyButton();
    }
})();