您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Remove obtrusive elements of a Whova browser session
// ==UserScript== // @name Whova Session Streamlined // @namespace https://github.com/amclark42/whova-session-streamlined // @version 1.1 // @description Remove obtrusive elements of a Whova browser session // @author Ash Clark // @match https://whova.com/portal/webapp/* // @license Unlicense // ==/UserScript== (function() { 'use strict'; console.log("Userscript loaded."); /* Create an internal CSS stylesheet for this page. */ let addStyles = function () { var css, styles = ''; css = document.createElement('style'); styles += ".no-notify .small-red-dot, .no-notify .notification-circle,\n" + ".no-notify .red-tag.solid-tag { display: none; }\n"; styles += ".btn-toggle { padding: 1em 0.5em; }\n"; styles += ".btn-toggle:hover, .btn-toggle:focus { background-color: #cde }\n"; styles += ".btn-toggle svg { margin: 0 0.5em; }\n"; styles += ".whova-side-navigation-menu.collapsed { min-width:unset; width: auto; }\n" styles += ".collapsed.whova-side-navigation-menu #whova-side-navigation-base-section, " + ".collapsed.whova-side-navigation-menu #whova-side-nav-scroll { display:none; }\n" styles += ".main-content .page-content { flex: 1 1 90%; width: auto; }\n"; styles += ".session-media-hub-video-player #session-video-iframe, .session-media-hub-video-player .session-external-player-wrapper" + "{ height: 80vh; }"; styles += ".agendav3-session-details-page-container .agenda-v3-compact-boards-container" + "{ min-width: fit-content; }\n"; styles += ".tab-list-container { min-width: 350px; }\n"; styles += ".collapsed.tab-list-container { min-width: unset; }\n"; styles += ".collapsed.tab-list-container .tabs { flex-direction: column; }\n"; styles += ".collapsed.tab-list-container .tab-panel-container { display: none; }\n"; /* Add CSS styles to <head>. */ css.appendChild(document.createTextNode(styles)); document.getElementsByTagName('head')[0].appendChild(css); }; // END addStyles() /* Recreate a SVG icon from Bootstrap: https://icons.getbootstrap.com/icons/signpost-split/ */ const expandIcon = function () { var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), title = document.createElementNS('http://www.w3.org/2000/svg', 'title'), path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); svg.setAttributeNS(null, 'width', 16); svg.setAttributeNS(null, 'height', 16); svg.setAttributeNS(null, 'viewBox', '0 0 16 16'); svg.setAttributeNS(null, 'fill', 'currentColor'); title.appendChild(document.createTextNode('Toggle site navigation')); path.setAttributeNS(null, 'd', 'M7 7V1.414a1 1 0 0 1 2 0V2h5a1 1 0 0 1 .8.4l.975 1.3a.5.5 0 0 1 0 .6L14.8 5.6a1 1 0 0 1-.8.4H9v10H7v-5H2a1 1 0 0 1-.8-.4L.225 9.3a.5.5 0 0 1 0-.6L1.2 7.4A1 1 0 0 1 2 7h5zm1 3V8H2l-.75 1L2 10h6zm0-5h6l.75-1L14 3H8v2z'); svg.appendChild(title); svg.appendChild(path); return svg; }; // END expandIcon() /* Test a location pathname to determine if the current page is a Whova session. */ let isSessionPage = function(page) { var regex = /\/portal\/webapp\/[\w_]+\/Agenda\/\w+/g; return regex.test(page); }; // END isSessionPage() /* Tweak the DOM, set up styles, create event listeners. */ let onLoad = function() { var sidebarNav, collapseBtnSide, pageNow, pagePrev, sessionModded, mutationOptions, mutationObserver; pageNow = window.location.pathname; pagePrev = pageNow; /* Clone the base toggle button for other uses. */ collapseBtnSide = document.createElement('button'); collapseBtnSide.classList.add('btn-toggle'); /* Prepare the left-hand sidebar. */ sidebarNav = document.getElementsByClassName('whova-side-navigation-menu'); collapseBtnSide.setAttribute('id', 'toggle-sidenav'); collapseBtnSide.addEventListener('click', toggleCollapse); collapseBtnSide.appendChild(expandIcon()); /* Add custom CSS rules before directly modifying the DOM. */ addStyles(); if ( sidebarNav.length > 0 ) { sidebarNav = sidebarNav[0]; try { sidebarNav.prepend(collapseBtnSide); } catch (err) { console.warn("Could not modify the sidebar nav."); } } /* Only modify the session page if the first page IS the session page. */ if ( isSessionPage(pageNow) ) { updateSessionNav(); } /* Monitor changes to the page, since Whova doesn't fully reload the page when navigating around. */ mutationObserver = new MutationObserver( function(records) { pageNow = window.location.pathname; if ( pageNow !== pagePrev ) { pagePrev = pageNow; console.log("Whova site navigated to new page: "+pageNow); if ( isSessionPage(pageNow) ) { console.log("Navigated to a Whova session."); sessionModded = false; } } /* Make sure that the session tabs navbar has been loaded before making any changes. */ if ( isSessionPage(pageNow) && !sessionModded && document.getElementsByClassName('tab-list-container').length > 0 ) { /* Wait a bit before modifying the session navbar. */ setTimeout( function() { if ( !sessionModded ) { sessionModded = true; console.log("Modifying the session navbar."); /* There is a possibility that updateSessionNav() will not have worked. If so, sessionModded will be re-set and a future mutation may have better luck. */ sessionModded = updateSessionNav(); } }, 300); } }); // The kinds of observations to make. mutationOptions = { childList: true, subtree: true }; mutationObserver.observe(document, mutationOptions); }; // END onLoad() /* When a button is clicked to toggle a sidebar, try to toggle the 'collapsed' class on the button's parent. */ let toggleCollapse = function(event) { var container = event.target; if ( container.nodeName === "BUTTON" ) { container = container.parentElement; } else if ( container.nodeName === 'svg' ) { container = container.parentElement.parentElement; } else if ( container.nodeName === 'path' ) { container = container.parentElement.parentElement.parentElement; } else { console.warn(container.nodeName); return; } //console.log(container); container.classList.toggle('collapsed'); }; // END toggleCollapse() /* When one of the visible tabs is clicked on the right, open the sidebar. */ let toggleCollapseIncidentally = function() { document.getElementsByClassName('tab-list-container')[0].classList.toggle( 'collapsed', false); }; // END toggleCollapseIncidentally() /* Use a class to prevent notifications from showing up. */ let toggleNotifications = function() { document.getElementsByTagName('body')[0].classList.toggle('no-notify'); }; // END toggleNotifications() /* Prepare the right-hand sidebar inside a Whova session. Returns a boolean indicating whether modifications have been successfully made. */ let updateSessionNav = function() { var tabListNav, collapseBtnTab, notifyBtn; try { collapseBtnTab = document.createElement('button'); collapseBtnTab.classList.add('btn-toggle'); notifyBtn = collapseBtnTab.cloneNode(true); tabListNav = document.getElementsByClassName('tab-list-container'); /* Make sure the tabs nav is available before making changes. */ if ( tabListNav.length > 0 ) { tabListNav = tabListNav[0]; tabListNav.classList.add('collapsed'); } else { /* If there's nothing in the DOM we can augment, return early. */ return false; } collapseBtnTab.setAttribute('id', 'toggle-tablist'); collapseBtnTab.addEventListener('click', toggleCollapse); collapseBtnTab.appendChild(document.createTextNode("Toggle sidebar")); notifyBtn.appendChild(document.createTextNode("Toggle notifications")); notifyBtn.addEventListener('click', toggleNotifications); /* Add new elements to the page. */ tabListNav.prepend(notifyBtn); tabListNav.prepend(collapseBtnTab); /* Make sure that clicking a tab in the right-hand nav will toggle the sidebar open. */ document.querySelectorAll('.tabs .tab-btn').forEach( function(btn) { btn.addEventListener('click', toggleCollapseIncidentally); }); } catch (err) { /* Report the error in the console but recover from it. */ console.warn(err); console.log("Userscript recovering.") return false; } return true; }; // END updateSessionNav() /* Whova keeps loading content after the page is "complete". As such, we wait a bit before running this userscript. */ if (document.readyState == 'complete') { setTimeout(function() { onLoad(); }, 2500); } else { // Wait until page has loaded, then wait a bit more. window.addEventListener('load',function() { setTimeout(function() { onLoad(); }, 2500); }); } })();