/*EvaluationKIT START*/var evalkit_jshosted = document.createElement('script');evalkit_jshosted.setAttribute('defer', 'defer');evalkit_jshosted.setAttribute('type', 'text/javascript');evalkit_jshosted.setAttribute('src', 'https://emich.evaluationkit.com/canvas/js');document.getElementsByTagName('head')[0].appendChild(evalkit_jshosted);/*EvaluationKIT END*/ //Run ASAP $(document).ready(function(){ var RegX = new RegExp(/\/courses\/\d+\/settings/); if (ENV.current_user_roles !== undefined) { if( //Restricting the following code to pages that match the above regex (RegX.test(location.pathname)) && //Restricting the following code to non-admin users ($.inArray('admin', ENV.current_user_roles) == -1) ) { //Removing delete, copy, import, export, reset, and conclude course buttons $('.delete_course_link').remove(); $('.copy_course_link').remove(); //$('.import_content').remove(); //$("a:contains('Export Course Content')").remove(); $('.reset_course_content_button').remove(); $("a:contains('Conclude this Course')").remove(); //$("a:contains('more options')").remove(); //$('.btn-primary').remove(); //$("button:contains('Update Course Details')").remove(); //Here are Canvas discussions on disabling the Start/End date fields in course settings //https://community.canvaslms.com/t5/Admin-Group/Javascript-to-disable-datepicker/td-p/108682 //https://community.canvaslms.com/t5/Developers-Group/Disable-Changing-Course-Start-and-End-Dates/td-p/310181/page/2 //Disable these text fields/dropdowns $("#course_time_zone").prop('disabled',true); $("#course_start_at").prop('disabled',true); $("#course_conclude_at").prop('disabled',true); $("#course_locale").prop('disabled',true); $("#course_license").prop('disabled',true); $("#course_course_visibility").prop('disabled',true); $("#course_course_format").prop('disabled',true); $("#course_public_description").prop('disabled',true); //Disable these checkboxes $("#course_restrict_enrollments_to_course_dates").prop('disabled',true); $("#course_restrict_student_past_view").prop('disabled',true); $("#course_restrict_student_future_view").prop('disabled',true); $("#course_filter_speed_grader_by_student_group").prop('disabled',true); $("#course_grading_standard_enabled").prop('disabled',true); $("#course_usage_rights_required").prop('disabled',true); $("#course_custom_course_visibility").prop('disabled',true); $("#course_indexed").prop('disabled',true); //Disabling the course details form //$("#course_form").find("input:not(:disabled), select:not(:disabled), textarea:not(:disabled), button:not(:disabled)").prop("disabled",true); } } }); //After page load $(window).bind("load", function() { var RegX = new RegExp(/\/courses\/\d+\/settings/); if( //Restricting the following code to pages that match the above regex (RegX.test(location.pathname)) && //Restricting the following code to non-admin users ($.inArray('admin', ENV.current_user_roles) == -1) ) { //Disabling the course dates calendar button $(".ui-datepicker-trigger").prop("disabled",true); } }); //////////////////////////////////////////////////// // DESIGNPLUS CONFIG // //////////////////////////////////////////////////// // Legacy var DT_variables = { iframeID: '', // Path to the hosted USU Design Tools path: 'https://designtools.ciditools.com/', templateCourse: '39839', // OPTIONAL: Button will be hidden from view until launched using shortcut keys hideButton: true, // OPTIONAL: Limit by course format limitByFormat: false, // Change to true to limit by format // adjust the formats as needed. Format must be set for the course and in this array for tools to load formatArray: [ 'online', 'on-campus', 'blended' ], // OPTIONAL: Limit tools loading by users role limitByRole: false, // set to true to limit to roles in the roleArray // adjust roles as needed roleArray: [ 'student', 'teacher', 'admin' ], // OPTIONAL: Limit tools to an array of Canvas user IDs limitByUser: false, // Change to true to limit by user // add users to array (Canvas user ID not SIS user ID) userArray: [ '1234', '987654' ] }; // New DpPrimary = { lms: 'canvas', templateCourse: '81582', hideButton: true, extendedCourse: '', // added in sub-account theme sharedCourse: '', // added from localStorage courseFormats: [], canvasRoles: [], canvasUsers: [], canvasCourseIds: [], plugins: [], excludedModules: [], includedModules: [], lang: 'en', defaultToLegacy: true, enableVersionSwitching: true, } // merge with extended/shared customizations config DpConfig = { ...DpPrimary, ...(window.DpConfig ?? {}) } $(function () { const uriPrefix = (location.href.includes('.beta.')) ? 'beta.' : ''; const toolsUri = (DpConfig.toolsUri) ? DpConfig.toolsUri : `https://${uriPrefix}designplus.ciditools.com/`; $.getScript(`${toolsUri}js/controller.js`); }); //////////////////////////////////////////////////// // END DESIGNPLUS CONFIG // //////////////////////////////////////////////////// /* * EMU Canvas - Global Custom Navigation (lean) * Adds "Success" and "Wellness" to the Canvas global nav. * - Idempotent and SPA-safe (re-injects on client-side navigation) * - Matches native icon size, centers SVGs, and keeps strokes crisp * - Uses Canvas color variables for normal/active tints */ // Changelog: 2025-10-17 - labels -> "Success"/"Wellness"; UTM links added. (function () { "use strict"; // Abort if we already ran, iframes, or native Canvas mobile shells if (window.__EMU_CUSTOM_NAV__?.installed) return; try { if (window.top !== window.self) return; } catch { return; } const userAgent = navigator.userAgent || ""; if (/\b(CanvasKit|Instructure|Canvas iOS|Canvas Android)\b/i.test(userAgent)) return; // IDs and config const CANVAS_MENU_ID = "menu"; const STYLE_ID = "emu-canvas-custom-nav-css"; const NAV_LINKS = [ { id: "student-success", label: "Success", href: "https://www.emich.edu/student-success/?utm_source=canvas&utm_medium=website&utm_campaign=global_nav", svg: ` `.trim() }, { id: "mental-health", label: "Wellness", href: "https://www.emich.edu/mental-health/?utm_source=canvas&utm_medium=website&utm_campaign=global_nav", svg: ` `.trim() } ]; /** * Injects a small CSS block that: * - centers the SVGs in the icon circle * - mirrors native size via CSS vars * - applies Canvas tints and crisp pixel strokes */ function ensureStyles() { if (document.getElementById(STYLE_ID)) return; const style = document.createElement("style"); style.id = STYLE_ID; style.textContent = ` /* Center icons in the circle container */ #global-nav-student-success .menu-item-icon-container, #global-nav-mental-health .menu-item-icon-container { display: flex !important; align-items: center !important; justify-content: center !important; line-height: 0 !important; } /* Match Canvas icon size & color */ #menu li[id^="global-nav-"] .ic-icon-svg.menu-item__icon { width: var(--emu-nav-icon-w, 26px) !important; height: var(--emu-nav-icon-h, 26px) !important; display: block !important; margin: 0 auto !important; color: var(--ic-brand-global-nav-ic-icon-svg-fill) !important; } #menu li[id^="global-nav-"].ic-app-header__menu-list-item--active .ic-icon-svg.menu-item__icon { color: var(--ic-brand-global-nav-ic-icon-svg-fill--active) !important; } /* Crisp, consistent outlines for our two icons */ #global-nav-student-success svg, #global-nav-student-success svg *, #global-nav-mental-health svg, #global-nav-mental-health svg * { fill: none !important; stroke: currentColor !important; vector-effect: non-scaling-stroke !important; stroke-linecap: round !important; stroke-linejoin: round !important; stroke-width: var(--emu-nav-icon-stroke-px, 1.3px) !important; shape-rendering: geometricPrecision !important; } `.trim(); document.head.appendChild(style); } // Normalize SVG so it scales cleanly and centers within its viewBox function normalizeSvgAttributes(svgEl) { if (!svgEl) return; svgEl.setAttribute("preserveAspectRatio", "xMidYMid meet"); svgEl.removeAttribute("width"); svgEl.removeAttribute("height"); svgEl.querySelectorAll("[stroke-width]").forEach(n => n.removeAttribute("stroke-width")); } // Build one menu
  • with anchor, icon, label function createNavItem({ id, label, href, svg }) { const li = document.createElement("li"); li.id = `global-nav-${id}`; li.className = "menu-item ic-app-header__menu-list-item"; const link = document.createElement("a"); link.className = "ic-app-header__menu-list-link"; link.href = href; link.target = "_blank"; link.rel = "noopener noreferrer"; link.setAttribute("aria-label", label); link.setAttribute("data-tooltip", label); const iconContainer = document.createElement("div"); iconContainer.className = "menu-item-icon-container"; iconContainer.setAttribute("aria-hidden", "true"); const tpl = document.createElement("template"); tpl.innerHTML = svg; const svgEl = tpl.content.firstElementChild; if (svgEl) { iconContainer.appendChild(svgEl); normalizeSvgAttributes(svgEl); } const badge = document.createElement("span"); badge.className = "menu-item__badge"; const labelEl = document.createElement("div"); labelEl.className = "menu-item__text"; labelEl.textContent = label; iconContainer.appendChild(badge); link.append(iconContainer, labelEl); li.appendChild(link); return li; } // Find the Help item; we insert after it (fallback: end of the menu) function findHelpAnchor() { const helpLink = document.querySelector("#global_nav_help_link"); return helpLink ? helpLink.closest("li") : null; } // Insert both items exactly once (idempotent) function insertNavItems() { const menu = document.getElementById(CANVAS_MENU_ID); if (!menu) return false; let anchor = findHelpAnchor() || menu.lastElementChild; for (const def of NAV_LINKS) { const existing = document.getElementById(`global-nav-${def.id}`); if (existing) { anchor = existing; continue; } const li = createNavItem(def); (anchor || menu).parentNode.insertBefore(li, (anchor || menu).nextSibling); anchor = li; } return true; } /** * Mirror the native icon size and set a matching stroke width. * Reads a native icon’s computed size and writes CSS variables. */ function applyIconSizing() { const sampleIcon = document.querySelector('#menu .ic-app-header__menu-list-item .ic-icon-svg') || document.querySelector('#menu .ic-app-header__menu-list-item .menu-item-icon-container img'); let targetSizePx = 26; if (sampleIcon) { const cs = getComputedStyle(sampleIcon); const w = parseFloat(cs.width) || 0; const h = parseFloat(cs.height) || 0; targetSizePx = Math.max(16, Math.min(w || h || 26, 48)); } // Chosen to match the approved look (~1.3px at 26px) const strokeAt26 = 1.3; const strokePx = Math.max(1, Math.min((targetSizePx / 26) * strokeAt26, 2.4)); const root = document.documentElement.style; root.setProperty("--emu-nav-icon-w", `${Math.round(targetSizePx)}px`); root.setProperty("--emu-nav-icon-h", `${Math.round(targetSizePx)}px`); root.setProperty("--emu-nav-icon-stroke-px", `${+strokePx.toFixed(2)}px`); } /** One-time start: inject styles, insert items, size icons */ function start() { ensureStyles(); if (insertNavItems()) applyIconSizing(); } /** Boot + lightweight SPA handling */ if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", start, { once: true }); } else { start(); } window.addEventListener("resize", applyIconSizing, { passive: true }); // Re-run on SPA navigation with a tiny hook ["pushState", "replaceState"].forEach(fn => { if (history[`__emuPatched_${fn}`]) return; const original = history[fn]; history[fn] = function () { const result = original.apply(this, arguments); window.dispatchEvent(new Event("emu:navigate")); return result; }; history[`__emuPatched_${fn}`] = true; }); window.addEventListener("popstate", () => window.dispatchEvent(new Event("emu:navigate"))); let navTimer = 0; window.addEventListener("emu:navigate", () => { clearTimeout(navTimer); navTimer = setTimeout(start, 120); }); // Minimal marker so we don’t double-inject window.__EMU_CUSTOM_NAV__ = { installed: true }; })();