Automatically expands all tabs in Canvas assignments and combines content
// ==UserScript==
// @name Canvas Tab Expander
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Automatically expands all tabs in Canvas assignments and combines content
// @author You
// @match https://*.instructure.com/courses/*/assignments/*
// @match https://elearn.ucr.edu/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
function expandAllTabs() {
// Get all tab content divs
const tabContents = document.querySelectorAll('.tab-pane.dp-panel-content');
// Remove classes and attributes that hide content
tabContents.forEach(content => {
// Remove Bootstrap's tab hiding classes
content.classList.remove('fade');
content.classList.add('show', 'active');
// Remove any inline display:none styling
content.style.removeProperty('display');
// Remove hidden attribute
content.removeAttribute('hidden');
// Force display block
content.style.display = 'block';
// Remove aria-hidden attribute
content.removeAttribute('aria-hidden');
});
// Modify the tab navigation to show all tabs as active
const tabNavs = document.querySelectorAll('.nav-link.dp-panel-heading');
tabNavs.forEach(tab => {
tab.classList.add('active');
tab.setAttribute('aria-selected', 'true');
});
// Also expand any nested accordion panels
const accordionPanels = document.querySelectorAll('.dp-panel-content[style*="display: none"]');
accordionPanels.forEach(panel => {
panel.style.display = 'block';
const toggler = panel.previousElementSibling?.querySelector('.dp-panel-toggler');
if (toggler) {
toggler.setAttribute('aria-expanded', 'true');
}
});
// Remove the tab-content active class restriction
const tabContentContainer = document.querySelector('.tab-content');
if (tabContentContainer) {
tabContentContainer.classList.remove('active');
// Add custom CSS to override Bootstrap's tab display logic
const style = document.createElement('style');
style.textContent = `
.tab-content > .tab-pane {
display: block !important;
opacity: 1 !important;
}
.dp-panel-content {
display: block !important;
}
`;
document.head.appendChild(style);
}
}
// Function to create and add the expand button
function addExpandButton() {
const existingButton = document.getElementById('expandAllTabsButton');
if (!existingButton) {
const expandButton = document.createElement('button');
expandButton.id = 'expandAllTabsButton';
expandButton.textContent = 'Expand All Tabs';
expandButton.className = 'Button Button--primary';
expandButton.style.margin = '10px 0';
expandButton.addEventListener('click', expandAllTabs);
const contentArea = document.querySelector('.description.user_content');
if (contentArea) {
contentArea.insertBefore(expandButton, contentArea.firstChild);
}
}
}
// Wait for the page to load
function init() {
addExpandButton();
expandAllTabs();
// Add a mutation observer to handle dynamically loaded content
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
expandAllTabs();
}
});
});
const config = { childList: true, subtree: true };
observer.observe(document.body, config);
}
// Run on page load
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// Also run after a short delay to catch any dynamic content
setTimeout(init, 1000);
})();