fix: improve menu detector

This commit is contained in:
JellyBrick
2025-07-11 23:00:38 +09:00
parent b48e05ab28
commit c44d5ea111
4 changed files with 57 additions and 27 deletions

View File

@ -13,7 +13,6 @@ import { DownloadButton } from './templates/download';
import type { RendererContext } from '@/types/contexts'; import type { RendererContext } from '@/types/contexts';
import type { DownloaderPluginConfig } from './index'; import type { DownloaderPluginConfig } from './index';
let menu: HTMLElement | null = null;
let download: () => void; let download: () => void;
const [downloadButtonText, setDownloadButtonText] = createSignal<string>(''); const [downloadButtonText, setDownloadButtonText] = createSignal<string>('');
@ -21,14 +20,10 @@ const [downloadButtonText, setDownloadButtonText] = createSignal<string>('');
let buttonContainer: HTMLDivElement | null = null; let buttonContainer: HTMLDivElement | null = null;
const menuObserver = new MutationObserver(() => { const menuObserver = new MutationObserver(() => {
if (!menu) { const menu = getSongMenu();
menu = getSongMenu();
if (!menu) {
return;
}
}
if ( if (
!menu ||
menu.contains(buttonContainer) || menu.contains(buttonContainer) ||
!isMusicOrVideoTrack() || !isMusicOrVideoTrack() ||
!buttonContainer !buttonContainer

View File

@ -3,7 +3,10 @@ import keyEventAreEqual from 'keyboardevents-areequal';
import { render } from 'solid-js/web'; import { render } from 'solid-js/web';
import { getSongMenu } from '@/providers/dom-elements'; import { getSongMenu } from '@/providers/dom-elements';
import { isMusicOrVideoTrack } from '@/plugins/utils/renderer/check'; import {
isMusicOrVideoTrack,
isPlayerMenu,
} from '@/plugins/utils/renderer/check';
import { t } from '@/i18n'; import { t } from '@/i18n';
@ -152,7 +155,12 @@ export const onPlayerApiReady = async (
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
const menu = getSongMenu(); const menu = getSongMenu();
if (menu?.contains(pipButtonContainer) || !isMusicOrVideoTrack()) { console.log(isPlayerMenu(menu));
if (
menu?.contains(pipButtonContainer) ||
!isMusicOrVideoTrack() ||
!isPlayerMenu(menu)
) {
return; return;
} }

View File

@ -7,7 +7,10 @@ import { getSongMenu } from '@/providers/dom-elements';
import { PlaybackSpeedSlider } from './components/slider'; import { PlaybackSpeedSlider } from './components/slider';
import { t } from '@/i18n'; import { t } from '@/i18n';
import { isMusicOrVideoTrack } from '@/plugins/utils/renderer/check'; import {
isMusicOrVideoTrack,
isPlayerMenu,
} from '@/plugins/utils/renderer/check';
const MIN_PLAYBACK_SPEED = 0.07; const MIN_PLAYBACK_SPEED = 0.07;
const MAX_PLAYBACK_SPEED = 16; const MAX_PLAYBACK_SPEED = 16;
@ -83,7 +86,12 @@ export const onPlayerApiReady = () => {
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
const menu = getSongMenu(); const menu = getSongMenu();
if (menu && !menu.contains(sliderContainer) && isMusicOrVideoTrack()) { if (
menu &&
!menu.contains(sliderContainer) &&
isMusicOrVideoTrack() &&
isPlayerMenu(menu)
) {
menu.prepend(sliderContainer); menu.prepend(sliderContainer);
} }
}); });

View File

@ -1,20 +1,39 @@
export const isMusicOrVideoTrack = () => { export const isMusicOrVideoTrack = () => {
let menuUrl = document.querySelector<HTMLAnchorElement>( for (const menuSelector of document.querySelectorAll<
'tp-yt-paper-listbox [tabindex="0"] #navigation-endpoint', HTMLAnchorElement & {
)?.href; data: {
watchEndpoint: {
if (!menuUrl?.includes('watch?')) { videoId: string;
menuUrl = undefined; };
// check for podcast addToPlaylistEndpoint: {
for (const it of document.querySelectorAll( videoId: string;
'tp-yt-paper-listbox [tabindex="-1"] #navigation-endpoint', };
)) { clickTrackingParams: string;
if (it.getAttribute('href')?.includes('podcast/')) { };
menuUrl = it.getAttribute('href')!; }
break; >('tp-yt-paper-listbox #navigation-endpoint')) {
} if (
menuSelector?.data?.addToPlaylistEndpoint?.videoId ||
menuSelector?.data?.watchEndpoint?.videoId
) {
return true;
} }
} }
return false;
return !!menuUrl; };
export const isPlayerMenu = (menu?: HTMLElement | null) => {
return (
menu?.parentElement as
| (HTMLElement & {
ytEventForwardingBehavior: {
forwarder_: {
eventSink: HTMLElement;
};
};
})
| null
)?.ytEventForwardingBehavior?.forwarder_?.eventSink?.matches(
'ytmusic-menu-renderer.ytmusic-player-bar',
);
}; };