/*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(
''
);
// })();
}
/*
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'
}
$('