NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name LinkFlagger // @version 81 // @author Grant Johnson // @author Grey Winert // @description Highlights brainhoney and box links and images. // @include *brightspace.com* // @require http://code.jquery.com/jquery-latest.js // @run-at document-end // ==/UserScript== window.addEventListener("load", function () { if (document.title == "Login - Brigham Young University - Idaho") { swspoilers(); // Log in page easter egg } // Clean or flag var ciframe = document.querySelectorAll("iframe"); if (ciframe.length > 0) { var dctitle = document.querySelector("h1[class*='d2l-page-title']"); // Get the page title. if (dctitle === null) { dctitle = "no title"; // if element is null, set a fake value } else { dctitle = dctitle.textContent; // if element exsists, reuse variable to title } if (dctitle == "Edit HTML File") { fixIssues(); // Fix issues if on edit page } else if (ciframe[0].className.indexOf('d2l-iframe') === 0) { flagCode(); // Otherwise flag page } } var bs, is, brs, divs, bolds, spans, as, empty, altimg, body, emdivs, baddiv, youtube, equila; function fixIssues() { // Credit to Eric Julander for the super ugly and unconventional fix! var stickyElement = $("a[role='button'] span:contains('Select a Document Template')"); if(!$("a[role='button'] span:contains('Select a Document Template')").text()){ stickyElement = $($(".vui-icon-custom")[0]); console.log("We are doomed!"); } stickyElement.parent().after('<a type="button" roll="button" class="d2l-button vui-button" id="fixstuff" style="vertical-align: top;"><strong>BETA:</strong> Fix issues. <em>Can interfere with formating</em></a>'); // Generate button document.getElementById("fixstuff").addEventListener("click", function () { cleanCode(); // actualy clean the code cleanCode(); // Run again for good measure cleanCode(); // Why the heck not cleanCode(); // 4th time might be the charm? openhtmleditor(); // open the HTML editor and fix a bunch of stuff $("a[id*='fixstuff']").html('<strong style="color: #00cc00;">Issues fixed!</strong>'); // set the button to notify user that it ran. }); } function cleanCode() { body = ciframe[0].contentWindow.document.querySelectorAll("*"); $(body).filter("[style*='bold']").contents().wrap('<strong/>'); // wrap bolds with strongs $(body).filter("[style*='bold']").removeAttr("style"); // wrap bolds with strongs $(body).filter("div:empty[id!='main'][class!='overlay'][id!='header'][id!='article'][class!='drop-content'][class!='drop-down'][class!=' list-columns'][class!='list-columns'][class!='check-wrapper'][class!='list-columns two']").contents().unwrap(); // remove empty divs $(body).filter("div[id!='main'][id!='header'][id!='overlay1'][id!='article'][class!='column'][class!='drop-content'][class!=' list-columns'][class!='list-columns'][class!='drop-down'][class!='slide'][class!='carousel'][class!='check-wrapper'][class!='list-columns two']").contents().unwrap().wrap('<p/>'); // wrap divs with text in ps $(body).filter("img:not([alt])").attr("alt", "Course Image"); // set images without an alt tag to have an empty one $(body).filter("b").contents().unwrap().wrap('<strong/>'); // wrap b tags with strongs $(body).filter("i").contents().unwrap().wrap('<em/>'); // wrap i tags with em tags if(!"span([class])") { $(body).filter("span:not([style])").contents().unwrap(); } $(body).filter("a:not([target='_blank'])").attr("target", "_blank"); $(body).filter("strong:empty, em:empty, br, b:empty").remove(); $(body).filter("iframe[src*='youtube.com/embed/']").attr("height", "500px"); $(body).filter("iframe[src*='youtube.com/embed/']").attr("width", "100%"); $(body).filter("iframe[src*='content.byui.edu/file/']").attr("height", "500px"); $(body).filter("iframe[src*='content.byui.edu/file/']").attr("width", "100%"); $(body).filter("a[href*='d2l/']").filter('a[href*="/calendar/"]').contents().unwrap(); $(body).filter("a[href*='d2l/']").filter('a[href*="/home/"]').contents().unwrap(); } function openhtmleditor() { document.querySelector('a[title*="HTML Source Editor"]').click(); var pagetitle = document.querySelector('input[id*="topicTitle"]').getAttribute("value"); // Get activity title var checkExist = setInterval(function() { if ($('iframe[src*="/d2l/tools/blank.html"]').length) { clearInterval(checkExist); var sourceiframe = document.querySelector('iframe[src*="/d2l/tools/blank.html"]'); sourceiframe.onload = function() { var minibody = sourceiframe.contentWindow.document.querySelectorAll("*"); // Only elements from the editing frame var sourcecodeelement = sourceiframe.contentWindow.document.querySelector("textarea[class='d2l-htmleditor-dialog-textarea']"); var sourcecode = sourcecodeelement.innerHTML; // Make human readable sourcecode = sourcecode.replace(/>/g , '>'); sourcecode = sourcecode.replace(/</g , '<'); // Make Changes sourcecode = sourcecode.replace(/<title>(.*?)</g, "<title>" + pagetitle + "<"); // Sync page title sourcecode = sourcecode.replace(/“/g, "\""); sourcecode = sourcecode.replace(/”/g, "\""); sourcecode = sourcecode.replace(/‘/g, "\'"); sourcecode = sourcecode.replace(/’/g, "\'"); sourcecode = sourcecode.replace(/–/g, " - "); sourcecode = sourcecode.replace(/—/g, "-"); sourcecode = sourcecode.replace(/<p><\/p>/g, ""); // get rid of empty paragraphs sourcecode = sourcecode.replace(/<h1><\/h1>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<h2><\/h2>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<h3><\/h3>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<h4><\/h4>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<h5><\/h5>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<h6><\/h6>/g, ""); // get rid of empty headers sourcecode = sourcecode.replace(/<a><\/a>/g, ""); // get rid of empty links sourcecode = sourcecode.replace(/<span><\/span>/g, ""); // get rid of empty links // Return to origional syntax sourcecode = sourcecode.replace(/>/g , '>'); sourcecode = sourcecode.replace(/</g , '<'); // Set modified code to the page sourcecodeelement.innerHTML = sourcecode; // Notify user to save changes $(minibody).filter("[class*='d2l-checkbox-container']").after('<p><em><strong style="color: #FF0000;">LinkFlagger:</strong> Changes have been made to this source code, please Save it.</em></p>'); }; } }, 100); } function flagCode() { body = ciframe[0].contentWindow.document.querySelectorAll("*"); // grabs all the elements from the iframe. // Set the vars once var bhlink = $(body).filter("a[href*='brainhoney.com']"); // If link element contains link from brainhoney var boxlink = $(body).filter("a[href*='box.com']"); // If link element contains link from box var benlink = $(body).filter("a[href*='courses.byui.edu']"); // If link element is from benjamin server var bolds = $(body).filter("[style*='bold']"); // If element has bold styling var badtar = $(body).filter("a:not([target='_blank'],[class*='triggerOverlay'],[id*='saveResults'])"); // If link has incorect target var alimage = $(body).filter("img:not([alt])"); // Images with no alt attribute var bhimage = $(body).filter("img[src*='brainhoney']"); // Images from BrainHoney var emlink = $(body).filter("a:empty"); // Empty Links. var dynlink = $(body).filter("a[href*='d2l/']").filter("a[href*='/home'], a[href*='/viewContent'], a[href*='/calendar']"); // Links that do not update when cloned var scripts = $(body).filter("script[src*='course.js'], script[src*='online.js']"); //Flag elements $([bhlink, boxlink, benlink, dynlink]).each( function() { $(this).css({ "color" : "#d9432f","outline" : "3px solid #d9432f","background" : "repeating-linear-gradient(135deg, #ffcdd2, #ffcdd2 5px, #ffffff 5px, #ffffff 10px)"}); }); $(bolds ).css({"outline" : "3px solid #689F38", "background" : "repeating-linear-gradient( 45deg, #DCEDC8, #DCEDC8 5px, #ffffff 5px, #ffffff 10px)"}); $(badtar ).css({"border" : "3px solid #ffb700", "background" : "repeating-linear-gradient(135deg, #FFE0B2, #FFE0B2 5px, #ffffff 5px, #ffffff 10px)"}); $(emlink ).css({"border" : "3px solid #0057e7"}); $(bhimage).css({"border" : "5px solid #d9432f"}); $(alimage).css({"outline" : "5px solid #176ced"}); // Set titles seterrortitles(bhlink , 'This is an iLearn 2.0 link, '); seterrortitles(boxlink , 'This a Box link, '); seterrortitles(benlink , 'This is a Benjamin link, '); seterrortitles(bolds , 'Embeded font-weight, '); seterrortitles(badtar , 'This link does not open in a new window, '); seterrortitles(emlink , 'This link has an empty href or text, '); seterrortitles(bhimage , 'This image is from BrainHoney, '); seterrortitles(alimage , 'This Image has no alt text, '); seterrortitles(dynlink , 'This link is a Static IL3 link and WILL NOT update when coppied, '); // Flag filepath and page title flagflepath(document.querySelector("div[class*='d2l-fileviewer-text']"), document.querySelector("ol[class*='vui-breadcrumbs']")); // Checks File path flagpgtitle(document.querySelector("h1[class*='d2l-page-title']"), ciframe[0].contentWindow.document.querySelector("title")); // Checks the titles if ($(scripts).length < 1) { $(ciframe[0]).css({"border-bottom": "20px solid #ff0000"}).after('<p style="color: #d9432f"><strong>There is no course.js script.</strong><p>'); } } function flagflepath(flepath, pathdiv) { if (flepath.getAttribute('data-location').includes('Files')) { $(pathdiv).css({ "border" : "3px solid #d9432f", "background" : "repeating-linear-gradient(45deg, #ffcdd2, #ffcdd2 5px, #ffffff 5px, #ffffff 10px)" }); $(pathdiv).attr("title", "Error: The filepath contains the words \'Course Files\' or \'Content Files\'."); } } function flagpgtitle(dctitle, httitle) { if ($(body).filter("title").length === 0) { $(dctitle).css({ "border" : "3px solid #176ced", "background" : "repeating-linear-gradient(135deg, #BBDEFB, #BBDEFB 5px, #ffffff 5px, #ffffff 10px)" }); $(dctitle).attr("title", "Error: No Title Found"); } else if (dctitle.textContent != httitle.textContent) { $(dctitle).css({ "border" : "3px solid #176ced", "background" : "repeating-linear-gradient(135deg, #BBDEFB, #BBDEFB 5px, #ffffff 5px, #ffffff 10px)" }); $(dctitle).attr("title", "Error: The HTML title \"" + httitle.textContent + "\" does not match the document title \"" + dctitle.textContent + "\""); } } function seterrortitles(elements, titletext) { var newtitle = ''; var curtitle = ''; for (i = 0; i < elements.length; i++) { if (elements[i] !== undefined) { if (elements[i].title.indexOf('Issues') === 0) { curtitle = ''; curtitle = elements[i].getAttribute('title'); newtitle = curtitle + titletext; } else { newtitle = 'Issues: ' + titletext; } elements[i].setAttribute('title', newtitle); } } } function swspoilers() { $(document.querySelector("h1[class*='d2l-login-portal-heading']")).html('<h1 style="font-size: 36px; text-align: center; color: #ff0000"><span style="font-weight:bold">"WHY IS IT SNOWING IN APRIL!?!?!"</span></h1><br><center><img width="40%" src="https://media.giphy.com/media/1RxlWYJ5hMYbS/giphy.gif"></center>'); } });