Adds an additional "Add to Playlist" buttons for easier and quicker access.
Version au
// ==UserScript==
// @name SoundCloud: Additional "Add to playlist" button
// @description Adds an additional "Add to Playlist" buttons for easier and quicker access.
// @version 0.8
// @author iammordaty
// @namespace https://github.com/iammordaty
// @match https://soundcloud.com/*
// @license MIT
// @grant none
// @icon https://a-v2.sndcdn.com/assets/images/sc-icons/favicon-2cadd14bdb.ico
// ==/UserScript==
// This must be unique on the page
const ANIMATION_NAME = 'IAMMORDATY-SC-AATPB-ON-NODE-INSTERTED';
// https://davidwalsh.name/detect-node-insertion
document.head.insertAdjacentHTML('beforeend', `
<style>
@keyframes ${ANIMATION_NAME} {
from { opacity: 0.99; }
to { opacity: 1; }
}
.soundList__item, .listenEngagement__footer, .trackList__item, .historicalPlays__item {
animation-duration: 0.001s;
animation-name: ${ANIMATION_NAME};
}
</style>
`);
const BUTTON_CLASS_NAMES = [
'sc-button-medium',
'sc-button-secondary',
'sc-button-small',
'sc-button-icon',
'sc-button',
'sc-button-responsive',
];
const getButtonClassList = refNodeClassList => {
const classList = BUTTON_CLASS_NAMES.filter(value => refNodeClassList.includes(value));
return [ ...classList, 'sc-button-add-to-playlist', 'sc-button-addtoset' ];
}
const createButton = (container, refNode) => {
const button = document.createElement('button');
button.setAttribute('role', 'button');
const classList = getButtonClassList([ ...refNode.classList ]);
button.classList.add(...classList);
// button.innerHTML = 'Add to Playlist';
button.setAttribute('title', 'Add this track to Playlist');
const innerDiv = document.createElement('div');
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 16 16');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('aria-hidden', 'true');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M3.25 7V4.75H1v-1.5h2.25V1h1.5v2.25H7v1.5H4.75V7h-1.5zM9 4.75h6v-1.5H9v1.5zM15 9.875H1v-1.5h14v1.5zM1 15h14v-1.5H1V15z');
path.setAttribute('fill', 'currentColor');
svg.appendChild(path);
innerDiv.appendChild(svg);
button.appendChild(innerDiv);
button.addEventListener('click', () => {
// Ignoring case sensitiveness in querySelectorAll: https://stackoverflow.com/a/38399344
container.querySelector('button[title="more" i]').click();
document.querySelector('button[title="add to playlist" i]').click();
}, false);
return button;
}
const insertButton = (button, refButton) => refButton.parentNode.insertBefore(button, refButton);
const onNodeInsert = ({ animationName, target: container }) => {
if (animationName !== ANIMATION_NAME) {
return;
}
const refButton = container.querySelector('.sc-button-more');
if (!refButton) {
return;
}
const button = createButton(container, refButton);
insertButton(button, refButton);
}
document.addEventListener('animationstart', onNodeInsert, false);