您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Добавляет плитку Яндекс.Музыки в результаты распознавания на сайте AHA-Music.
// ==UserScript== // @name AHA-Music + Yandex Music // @name:ru AHA-Music + Яндекс.Музыка // @description Добавляет плитку Яндекс.Музыки в результаты распознавания на сайте AHA-Music. // @namespace FerNikoMF // @version 1.0.0 // @match https://www.aha-music.com/* // @icon https://upload.wikimedia.org/wikipedia/commons/f/fa/Yandex_Music_icon_2023.svg // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; // URL для внешнего SVG логотипа Яндекс.Музыки const YANDEX_ICON_URL = "https://yastatic.net/s3/doc-binary/src/mediaservices/yandex_music_ru_whitebg.svg"; function tryAdd() { // Найдём контейнер с плитками — ориентируемся на любые ссылки сервисов const anyTile = document.querySelector('a[href*="spotify.com"], a[href*="deezer.com"], a[href*="apple.com"], a[href*="youtube.com"]'); if (!anyTile) return; // Если уже добавлено — выходим if (document.querySelector('.yandex-music-tile')) return; // Попробуем найти Deezer, если нет — возьмём последний шаблонный элемент let deezer = document.querySelector('a[href*="deezer.com"]'); let insertAfter = deezer; if (!insertAfter) { // ищем последний подходящий tile в той же группе const tiles = [...document.querySelectorAll('a[href*="spotify.com"], a[href*="apple.com"], a[href*="youtube.com"], a[href*="deezer.com"]')]; insertAfter = tiles.length ? tiles[tiles.length - 1] : anyTile; } // Берём параметры title/artist из URL const params = new URLSearchParams(window.location.search); const title = params.get('title') || ''; const artist = params.get('artist') || ''; const query = encodeURIComponent((artist + ' ' + title).trim() || ''); // Клонируем шаблон плитки (чтобы сохранить все классы/стили) const template = anyTile.cloneNode(true); const yTile = template.cloneNode(true); // пометка и проверка yTile.classList.add('yandex-music-tile'); // изменяем href yTile.href = query ? `https://music.yandex.ru/search?text=${query}` : 'https://music.yandex.ru/'; yTile.target = '_blank'; yTile.rel = 'noopener noreferrer'; // жёстко удалить все картинки и srcset/data-src, и удалить текстовые подписи внутри клона yTile.querySelectorAll('img').forEach(i => i.remove()); yTile.querySelectorAll('[srcset], [data-src], [data-lazy]').forEach(el => { el.removeAttribute('srcset'); el.removeAttribute('data-src'); el.removeAttribute('data-lazy'); }); // Удаляем текстовые узлы [...yTile.querySelectorAll('*')].forEach(el => { if (el.children.length === 0 && /\S/.test(el.textContent || '')) { el.textContent = ''; } }); // Создаём элемент <img> с вашим URL const yandexIcon = document.createElement('img'); yandexIcon.src = YANDEX_ICON_URL; yandexIcon.alt = 'Yandex Music Logo'; // === ИЗМЕНЁННЫЙ КОД ДЛЯ ИКОНКИ === // Устанавливаем ширину и высоту в 16px yandexIcon.style.width = '150px'; yandexIcon.style.height = '50px'; yandexIcon.style.flex = '0 0 auto'; // Найдём место для иконки const possibleImgContainer = yTile.querySelector('div, span, picture') || null; if (possibleImgContainer) { possibleImgContainer.innerHTML = ''; possibleImgContainer.appendChild(yandexIcon); } else { yTile.prepend(yandexIcon); } // === КОНЕЦ ИЗМЕНЕНИЙ === yTile.style.display = template.style.display || ''; yTile.style.alignItems = 'center'; yTile.style.justifyContent = 'center'; insertAfter.insertAdjacentElement('afterend', yTile); console.log('✅ Yandex Music плитка добавлена (16px external SVG).'); } // Наблюдение + безопасный интервал: DOM динамический const observer = new MutationObserver(() => { tryAdd(); }); observer.observe(document.body, { childList: true, subtree: true }); // резерв: попробуем несколько раз через интервалы (на случай долгой подгрузки) const maxAttempts = 12; // ~24 сек let attempts = 0; const intervalId = setInterval(() => { attempts++; tryAdd(); if (document.querySelector('.yandex-music-tile') || attempts >= maxAttempts) { clearInterval(intervalId); setTimeout(() => observer.disconnect(), 5000); } }, 2000); })();