/*EvaluationKIT START*/ var evalkit_jshosted = document.createElement("script"); evalkit_jshosted.setAttribute("defer", "defer"); evalkit_jshosted.setAttribute("type", "text/javascript"); evalkit_jshosted.setAttribute("src", "https://ccp.evaluationkit.com/canvas/js"); document .getElementsByTagName("head")[0] .appendChild(evalkit_jshosted); /*EvaluationKIT END*/ // https://s3.amazonaws.com/SSL_Assets/CCP/changetext2.js /* Javascript global file - Community College of Philadelphia Login Edits version: 0.0.1 author: Jason Stein Notes: Relies on Canvas loading jQuery History: Created - Feb 2014 Code added to replace support links below canvas login. Code added to replace placeholder for mobile login. Modified 4/28/14 Modified code to remove if statement for username - code provided by Instructure. Modified 5/5/2016 for new design */ if (window.location.href.indexOf("login") > -1) { var sp = $("#login_form label[for=pseudonym_session_unique_id]>span"); sp.text("CCP Username"); // } // the below function displays the login information // $(document).ready(function(){ // Code below works by ading in the placeholder but the label is shown // The below function displays the login information // $('#login_form label[for=pseudonym_session_unique_id]>span').text('Username'); // change forgot password text $("#login_forgot_password").text("New User/Don't know your password?"); $("#forgot_password_form label > span").text("CCP Email"); // Replace footer links $("#footer").html( 'Login Instructions Icon Login InstructionsCanvas Guides Icon Canvas GuidesHelp Desk Icon CCP Helpdesk Need help with Canvas? Contact Online Learning' ); // })(); } /* IVY.AI CHATBOT Addition to implement Ivy.ai chatbot author: Jeremy Harvey Created: 12/21/2023 Modified: 01/06/24 to disable on quiz pages */ if (!/\/quizzes|\/login/.test(window.location.href)) { const script = document.createElement("script"); script.src = "https://bot.ivy.ai/bot/script/category/28wd9NaExB5YQpMdajGqryKJ1kZ706mW"; script.referrerpolicy = "no-referrer-when-downgrade"; document.head.appendChild(script); script.addEventListener("load", () => { ivyapi.setVariable("user", ENV.current_user); }); } const TENANT_ID = "ccp"; /** * CANVAS INSIGHTS * Adds a script to the document body. * @returns {Promise} A promise that resolves when the script is loaded successfully, or rejects with an error if the script fails to load. */ function addScript() { const s3ScriptUrl = `https://s3.us-west-1.amazonaws.com/ddl.public/${TENANT_ID}/gradeExportButton.js`; return new Promise((resolve, reject) => { const script = document.createElement("script"); script.setAttribute("charset", "UTF-8"); script.setAttribute("src", s3ScriptUrl); script.onload = () => resolve(); script.onerror = (error) => reject(error); document.body.appendChild(script); }); } document.addEventListener("DOMContentLoaded", () => { addScript() .then(() => { if (window.addScript) { console.log('Loaded Insights script successfully'); } else { console.error('Insights script did not load correctly'); } }) .catch((error) => console.error('Error loading Insights script:', error)); }); /* SYLLABUS MENU ITEM REMOVAL Addition to remove native Syllabus tool after implementing Concourse Syllabus Modified: 2025-07-03 */ // Get the section-tabs-header-subtitle element let termElement = document.getElementById("section-tabs-header-subtitle"); // Function to restore visibility to incorrectly hidden elements function restoreIncorrectlyHiddenElements() { // Specifically target the css-1r50q5-gridRow class that's being incorrectly hidden const hiddenGridRows = document.querySelectorAll('span.css-1r50q5-gridRow[style*="display: none"]'); if (hiddenGridRows.length > 0) { console.log(`⚠️ Found ${hiddenGridRows.length} incorrectly hidden grid row elements. Restoring...`); hiddenGridRows.forEach(el => { // Remove the inline styles that hide the element el.style.display = ''; el.style.visibility = ''; el.style.height = ''; el.style.width = ''; el.style.overflow = ''; el.style.position = ''; el.style.opacity = ''; // Also check for any data-hidden-id attribute and remove it if (el.hasAttribute('data-hidden-id')) { const hiddenId = el.getAttribute('data-hidden-id'); el.removeAttribute('data-hidden-id'); // Remove any associated style element const styleEl = document.getElementById(`style-${hiddenId}`); if (styleEl) { styleEl.remove(); } } console.log('✅ Restored visibility to element:', el); }); } } // Set up a body visibility protection mechanism function ensureBodyVisibility() { const body = document.body; // Check if body has display:none or visibility:hidden const bodyStyle = window.getComputedStyle(body); if (bodyStyle.display === 'none' || bodyStyle.visibility === 'hidden') { console.log('⚠️ Body visibility issue detected! Restoring...'); body.style.display = ''; body.style.visibility = ''; body.style.opacity = '1'; // Also check for any style elements that might be hiding the body const styleElements = document.querySelectorAll('style'); for (const style of styleElements) { if (style.textContent.includes('body') && (style.textContent.includes('display: none') || style.textContent.includes('visibility: hidden'))) { console.log('⚠️ Found style element affecting body visibility:', style); style.remove(); } } } // Also check for incorrectly hidden elements restoreIncorrectlyHiddenElements(); } // Run the visibility checks immediately ensureBodyVisibility(); // Set up periodic checks for visibility issues const visibilityCheckInterval = setInterval(() => { ensureBodyVisibility(); restoreIncorrectlyHiddenElements(); }, 2000); // Function to check if current course should have syllabus hidden function shouldHideSyllabus() { if (!termElement) return false; const termText = termElement.innerText; return termText == "Summer 2025" || termText == "Fall 2025" || termText.includes("2026") || parseInt(termText.substring(termText.lastIndexOf(" ") + 1)) > 2025; } // Simplified function to hide syllabus by targeting the specific ID function hideSyllabusById() { if (!shouldHideSyllabus()) { console.log('ℹ️ Course term does not require syllabus hiding'); return false; } const syllabusLink = document.getElementById('syllabus-link'); if (syllabusLink) { // Find the parent element with class "section" const sectionParent = syllabusLink.closest('.section'); if (sectionParent) { console.log('✅ Found syllabus-link and its section parent. Hiding...'); sectionParent.style.display = 'none'; console.log('✅ Successfully hidden syllabus section'); return true; } else { console.log('⚠️ Found syllabus-link but no parent with class "section"'); return false; } } else { console.log('ℹ️ No element with id "syllabus-link" found'); return false; } } // Updated function to hide mobile syllabus menu item by targeting the gridRow container function hideMobileSyllabus() { if (!shouldHideSyllabus()) { console.log('ℹ️ Course term does not require mobile syllabus hiding'); return false; } // Look for links ending with "assignments/syllabus" const syllabusLinks = document.querySelectorAll('a[href$="assignments/syllabus"]'); let hiddenCount = 0; syllabusLinks.forEach(link => { // Check if this link is within a span.css-jkahvz-gridCol container const gridColContainer = link.closest('span.css-jkahvz-gridCol'); if (gridColContainer) { // Also verify it contains a span with css-1lrbdaw-text class (the text span) const textSpan = link.querySelector('span.css-1lrbdaw-text'); if (textSpan) { // Now find the parent css-f0qfa2-gridRow container that includes the icon const gridRowContainer = gridColContainer.closest('span.css-f0qfa2-gridRow'); if (gridRowContainer) { // Check if it's already hidden to avoid duplicate hiding if (gridRowContainer.style.display !== 'none') { console.log('✅ Found mobile syllabus link in gridRow container. Hiding...'); console.log('Link:', link.href); console.log('Text:', textSpan.textContent); console.log('GridRow Container:', gridRowContainer); // Hide the grid row container (this will hide both text and icon) gridRowContainer.style.display = 'none'; gridRowContainer.setAttribute('data-syllabus-hidden', 'true'); hiddenCount++; } } else { console.log('⚠️ Found mobile syllabus link but no css-f0qfa2-gridRow parent'); } } } }); if (hiddenCount > 0) { console.log(`✅ Successfully hidden ${hiddenCount} mobile syllabus menu item(s) with icons`); return true; } else { console.log('ℹ️ No mobile syllabus menu items found or all already hidden'); return false; } } // Enhanced function to set up persistent observer for dynamically loaded content function setupPersistentSyllabusObserver() { const observer = new MutationObserver((mutations) => { let shouldCheckDesktop = false; let shouldCheckMobile = false; mutations.forEach((mutation) => { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { // Check for desktop syllabus-link if (document.getElementById('syllabus-link')) { shouldCheckDesktop = true; } // Check for mobile syllabus links if (document.querySelectorAll('a[href$="assignments/syllabus"]').length > 0) { shouldCheckMobile = true; } } // Also check for attribute changes (like style changes on resize) if (mutation.type === 'attributes') { const target = mutation.target; // If a mobile syllabus gridRow container became visible again, hide it if (target.classList.contains('css-f0qfa2-gridRow') && target.hasAttribute('data-syllabus-hidden') && target.style.display !== 'none') { console.log('🔍 Mobile syllabus gridRow container became visible again, re-hiding...'); target.style.display = 'none'; } } }); if (shouldCheckDesktop) { console.log('🔍 Desktop syllabus link detected via observer'); hideSyllabusById(); } if (shouldCheckMobile) { console.log('🔍 Mobile syllabus links detected via observer'); hideMobileSyllabus(); } }); // Start observing with more comprehensive settings observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); console.log('🔍 Persistent syllabus observer started'); // Return the observer so it can be managed if needed return observer; } // Function to handle both desktop and mobile syllabus hiding function hideSyllabusMenuItems() { if (!shouldHideSyllabus()) { console.log('ℹ️ Course term does not require syllabus hiding'); return; } let desktopHidden = hideSyllabusById(); let mobileHidden = hideMobileSyllabus(); console.log(`Desktop hidden: ${desktopHidden}, Mobile hidden: ${mobileHidden}`); } // Set up persistent observer regardless of what we find initially let persistentObserver = null; // Check if its innerText is "Summer 2025" or more recent if (shouldHideSyllabus()) { console.log(`✅ Course term "${termElement.innerText}" requires syllabus hiding`); let syllabusElement = document.querySelector(".syllabus"); if (syllabusElement) { syllabusElement.style.display = "none"; } // Hide both desktop and mobile syllabus menu items hideSyllabusMenuItems(); // Set up persistent observer to handle dynamic changes persistentObserver = setupPersistentSyllabusObserver(); } else { console.log(`ℹ️ Course term "${termElement ? termElement.innerText : 'unknown'}" does not require syllabus hiding`); } // Remove "Syllabi" element from every course navigation menu let syllabiElement = document.querySelector(".context_external_tool_534902"); if (syllabiElement) { syllabiElement.style.display = "none"; } // Add resize event listener to handle responsive changes window.addEventListener('resize', function() { if (shouldHideSyllabus()) { // Small delay to allow the page to finish resizing setTimeout(() => { console.log('🔍 Window resized, checking for syllabus elements...'); hideSyllabusMenuItems(); }, 500); } }); // Add null checks for all element selections and ensure body visibility is maintained window.addEventListener('load', function() { ensureBodyVisibility(); restoreIncorrectlyHiddenElements(); // Run an additional check after a short delay setTimeout(() => { restoreIncorrectlyHiddenElements(); // Also re-check syllabus hiding after page load if (shouldHideSyllabus()) { hideSyllabusMenuItems(); } }, 1000); }); // Add a MutationObserver specifically for the css-1r50q5-gridRow elements const gridRowObserver = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.type === 'attributes' && mutation.attributeName === 'style' && mutation.target.classList.contains('css-1r50q5-gridRow')) { const style = mutation.target.style; if (style.display === 'none' || style.visibility === 'hidden') { console.log('⚠️ Protected grid row element was hidden. Restoring:', mutation.target); mutation.target.style.display = ''; mutation.target.style.visibility = ''; mutation.target.style.height = ''; mutation.target.style.width = ''; } } }); }); // Start observing all grid row elements document.querySelectorAll('.css-1r50q5-gridRow').forEach(el => { gridRowObserver.observe(el, { attributes: true }); }); // Also observe the document for new grid row elements const documentObserver = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // Check if the added node is a grid row if (node.classList && node.classList.contains('css-1r50q5-gridRow')) { gridRowObserver.observe(node, { attributes: true }); } // Also check children of the added node const gridRows = node.querySelectorAll('.css-1r50q5-gridRow'); gridRows.forEach(el => { gridRowObserver.observe(el, { attributes: true }); }); } }); } }); }); // Start observing the document documentObserver.observe(document.body, { childList: true, subtree: true }); (function () { window.SENSUS_CFG = { ltiDomain: 'https://inside.sensusaccess.com/', clientId: '130000000001241', consumerKey: 'aeebb8c3-1b1c-4448-03d4-08ddc3da8f40' } $('