您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds download links on freesound.org. Works with a button press, or automatically.
- // ==UserScript==
- // @name Fetch Download Links on FreeSound.org
- // @namespace Violentmonkey Scripts
- // @version 1.0.1
- // @description Adds download links on freesound.org. Works with a button press, or automatically.
- // @author Jupiter Liar
- // @license CC BY
- // @match https://freesound.org/*
- // @description 4/23/2024, 10:30:00 AM
- // @grant none
- // ==/UserScript==
- // Function to handle grabbing HTML from linked page and replacing Grab button
- function grabHtmlAndReplaceButton(button) {
- button.textContent = "Fetching...";
- // Find the parent search result element
- const searchResult = button.closest('.bw-search__result');
- // Find the first <a> element within the search result if available
- var link;
- if (searchResult) {
- link = searchResult.querySelector('a');
- } else {
- // If searchResult is not found, traverse up the DOM tree until we find an ancestor containing .bw-player
- var ancestor = button.parentElement;
- while (ancestor && !(ancestor.querySelector('.bw-player') && ancestor.querySelector('a'))) {
- ancestor = ancestor.parentElement;
- }
- // Once we find the ancestor containing .bw-player, find the first <a> element within it
- if (ancestor) {
- link = ancestor.querySelector('a');
- }
- }
- // Check if a link is found
- if (link) {
- // Fetch the linked page
- fetch(link.href)
- .then(response => response.text())
- .then(html => {
- // Create a temporary element to hold the fetched HTML
- const tempElement = document.createElement('div');
- tempElement.innerHTML = html;
- // Find the element with class "sound-download-button"
- const soundDownloadButton = tempElement.querySelector('.sound-download-button');
- const sidebarDownloadButton = tempElement.querySelector('.bw-sound__sidebar .btn-primary');
- // Replace the Grab button with the sound-download-button element
- if (soundDownloadButton) {
- // Replace the Grab button with the sound-download-button element
- button.parentNode.replaceChild(soundDownloadButton, button);
- } else if (sidebarDownloadButton) {
- button.parentNode.replaceChild(sidebarDownloadButton, button);
- } else {
- console.log('No download button found on the linked page');
- // Update the button text content if no download button is found
- button.innerText = "No button found";
- }
- })
- .catch(error => {
- console.error('Error fetching linked page:', error);
- button.textContent = "Error fetching page";
- });
- } else {
- console.log('No link found in search result');
- }
- }
- // Function to create and append grab buttons
- function createGrabButtons(parentElement, grabMode, additionalClass) {
- // If grabMode is true, insert grab buttons
- if (grabMode) {
- const grabberDiv = document.createElement('div');
- grabberDiv.classList.add('grabber');
- if (additionalClass) {
- grabberDiv.classList.add(additionalClass); // Add additional class if it exists
- }
- // grabberDiv.classList.add('in-row'); // Add in-row class
- // Create the Grab button
- const grabButton = document.createElement('button');
- grabButton.classList.add('grab-button');
- grabButton.textContent = 'Get download button';
- // Add event listener to the Grab button
- grabButton.addEventListener('click', function () {
- grabHtmlAndReplaceButton(this);
- });
- // Append the Grab button to the grabber div
- grabberDiv.appendChild(grabButton);
- // Append the grabber div to the parent element
- if (parentElement.classList.contains('bw-search__result')) {
- // If parentElement has class bw-search__result, append the grabberDiv as the second to last element
- const lastChild = parentElement.lastElementChild;
- parentElement.insertBefore(grabberDiv, lastChild);
- } else {
- // Else, appendChild normally
- parentElement.appendChild(grabberDiv);
- }
- }
- }
- function createInsertAllButton(topLevelElement) {
- // Create the container for "Insert all download buttons" button
- const insertAllContainer = document.createElement('div');
- insertAllContainer.classList.add('show-all-download-buttons');
- // Create the "Insert all download buttons" button
- const insertAllButton = document.createElement('button');
- insertAllButton.classList.add('btn-primary', 'w-100', 'insert-all-download-buttons');
- insertAllButton.textContent = 'Insert all download buttons';
- // Add event listener to the "Insert all download buttons" button
- insertAllButton.addEventListener('click', function () {
- clickAllGrabButtons();
- });
- // Append the button to the container
- insertAllContainer.appendChild(insertAllButton);
- // Insert the container before the very first search result
- topLevelElement.parentNode.insertBefore(insertAllContainer, topLevelElement);
- // Create the div for auto-insert option
- const autoInsertDiv = document.createElement('div');
- autoInsertDiv.classList.add('auto-insert-div');
- // Create the checkbox for auto-insert option
- const autoInsertCheckbox = document.createElement('input');
- autoInsertCheckbox.type = 'checkbox';
- autoInsertCheckbox.checked = localStorage.getItem('autoInsertCheckbox') === 'true'; // Check local storage for value
- // Add event listener to the auto-insert checkbox
- autoInsertCheckbox.addEventListener('change', handleAutoInsertChange);
- // Create the span for auto-insert option
- const autoInsertSpan = document.createElement('span');
- autoInsertSpan.textContent = 'Do this automatically';
- // Append checkbox and span to auto-insert div
- autoInsertDiv.appendChild(autoInsertCheckbox);
- autoInsertDiv.appendChild(autoInsertSpan);
- // Append auto-insert div to show-all-download-buttons container
- insertAllContainer.appendChild(autoInsertDiv);
- // Check if the checkbox is checked
- if (autoInsertCheckbox.checked) {
- clickAllGrabButtons();
- }
- }
- // Check if the current URL includes freesound.org/search
- if (window.location.href.includes("freesound.org/search")) {
- console.log('URL matched: freesound.org/search');
- // Find all instances of '.bw-search__result' within the 'main' element
- const searchResults = document.querySelectorAll('main .bw-search__result');
- // Loop through each search result
- searchResults.forEach(result => {
- // Find the first <a> element within the search result
- const firstLink = result.querySelector('a');
- // Check if a <a> element is found
- if (firstLink) {
- // Print the href attribute of the first <a> element to the console
- console.log('First link href:', firstLink.href);
- // If grabMode is true, insert a new div at the end of the search result
- createGrabButtons(result, true, '');
- } else {
- console.log('No link found in search result');
- }
- });
- // Find the very first search result element
- const firstSearchResult = document.querySelector('main .bw-search__result:first-child');
- // Check if the first search result element is found
- if (firstSearchResult) {
- createInsertAllButton(firstSearchResult);
- } else {
- console.log('No search results found');
- }
- } else {
- console.log('URL did not match: freesound.org/search');
- // Check if the page includes one or more instances of .bw-player
- const bwPlayers = document.querySelectorAll('.bw-player');
- if (bwPlayers.length >= 1) {
- console.log('One or more instances of .bw-player were found:', bwPlayers.length);
- // Initialize an array to store common ancestors
- var commonAncestors = [];
- // Loop through each .bw-player instance
- bwPlayers.forEach(player => {
- // Initialize an array to store ancestors of the current .bw-player instance
- var ancestors = [];
- // Find the parent element of the .bw-player instance
- const parentElement = player.parentNode;
- // Create and append grab buttons
- createGrabButtons(parentElement, true, 'in-row');
- // Traverse up the DOM tree and store ancestors until reaching the document body
- var ancestor = player.parentNode;
- while (ancestor !== document.body) {
- ancestors.push(ancestor);
- ancestor = ancestor.parentNode;
- }
- // Add ancestors of the current .bw-player instance to the common ancestors array
- commonAncestors = commonAncestors.length === 0 ? ancestors : commonAncestors.filter(ancestor => ancestors.includes(ancestor));
- });
- // Find the lowest-level common ancestor
- console.log("commonAncestors: ");
- commonAncestors.forEach(ancestor => {
- console.log(ancestor);
- });
- function findLowestLevelCommonAncestor(commonAncestors) {
- var lowestCommonAncestor = commonAncestors[0]; // Initialize with the first element
- // Iterate through the common ancestors array
- for (let i = 1; i < commonAncestors.length; i++) {
- const currentAncestor = commonAncestors[i];
- // Check if the current ancestor is deeper in the hierarchy than the current lowest common ancestor
- if (lowestCommonAncestor.contains(currentAncestor)) {
- lowestCommonAncestor = currentAncestor;
- }
- }
- return lowestCommonAncestor;
- }
- const lowestCommonAncestor = findLowestLevelCommonAncestor(commonAncestors);
- console.log('Lowest level common ancestor:', lowestCommonAncestor);
- // Pass the lowest-level common ancestor to the createInsertAllButton function
- createInsertAllButton(lowestCommonAncestor);
- } else {
- console.log('No instances of .bw-player were found');
- }
- }
- // Function to handle auto-insert checkbox change
- function handleAutoInsertChange() {
- // Get the auto-insert checkbox
- const autoInsertCheckbox = document.querySelector('.auto-insert-div input[type="checkbox"]');
- // Update the local storage value
- localStorage.setItem('autoInsertCheckbox', autoInsertCheckbox.checked);
- // Check if the checkbox is checked
- if (autoInsertCheckbox.checked) {
- clickAllGrabButtons();
- }
- }
- // Function to click all grab buttons
- function clickAllGrabButtons() {
- const grabButtons = document.querySelectorAll('.grab-button');
- grabButtons.forEach(button => {
- grabHtmlAndReplaceButton(button);
- });
- }
- // Add stylesheet to the page head
- const style = document.createElement('style');
- style.id = 'new-script-css';
- style.innerHTML = `
- .grabber {
- width: 100%;
- margin: 0 0 12px;
- text-align: center;
- }
- .grabber .grab-button {
- background: #CCC;
- padding: 4px 8px;
- border: 1px solid black;
- border-radius: 1em;
- }
- .grabber.in-row {
- margin-top: 12px;
- }
- .grabber.in-row .grab-button {
- font-size: .75em;
- }
- .grabber.in-row .btn-primary {
- padding: 9px 21px;
- }
- .show-all-download-buttons {
- margin-bottom: 32px;
- text-align: center;
- --sadb-border-style: 1px solid hsla(0, 0%, 0%, .5);
- border-bottom: var(--sadb-border-style);
- border-top: var(--sadb-border-style);
- }
- .insert-all-download-buttons {
- margin: 12px 0 6px;
- }
- .auto-insert-div {
- margin-bottom: 12px;
- justify-content: center;
- align-items: center;
- display: flex;
- }
- .auto-insert-div * {
- margin: 0 .35em;
- }
- `;
- document.head.appendChild(style);