// ==UserScript==
// @name DarkDLNure
// @namespace http://dl.nure.ua
// @version 1.4.11
// @description Робить сайт краще, виправляє неповну темну тему. Для студентів мого вишу.
// @author Mops
// @match https://dl.nure.ua/*
// @icon https://dl.nure.ua/pluginfile.php/1/theme_moove/favicon/1664384975/favicon.ico
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
// @ts-check
/**
* @template T
* @param {T | T[]} value
* @returns {T[]}
*/
function arrify(value) {
return Array.isArray(value) ? value : [value];
}
/**
* @typedef {Partial<CSSStyleDeclaration & Record<string, string>>} StyleOptions
*/
/**
* @param {StyleOptions} styles
*/
function styleDeclaration(styles) {
return Object.entries(styles).map(([cssProperty, cssValue]) => `${cssProperty.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()}:${cssValue};`).join("");
}
/**
* @typedef StyleMap
* @property {string | string[]} selector
* @property {string | string[]} [parent]
* @property {StyleOptions} styles
*/
/**
* @param {StyleMap[]} styleMaps
*/
function createStyles(...styleMaps) {
return styleMaps.map(
styleMap => arrify(styleMap.selector).map(
selector => {
function addParent(parent) {
return typeof parent === "string" && parent !== ""
? `${parent} ${selector}{${styleDeclaration(styleMap.styles)}}`
: `${selector}{${styleDeclaration(styleMap.styles)}}`
}
return Array.isArray(styleMap.parent) && styleMap.parent.length > 0
? styleMap.parent.map(parent => addParent(parent)).join("\n")
: addParent(styleMap.parent)
}
).join("\n")
).join("\n")
}
/**
* @param {string} selector
* @param {number} [timeout]
*/
function waitForElement(selector = "body", timeout = 0) {
return new Promise((resolve, reject) => {
if (timeout > 0) {
setTimeout(reject, timeout)
}
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(mutations => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelector(selector));
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
const themeDarkClass = "moove-darkmode"
const themeDarkSelector = `body.${themeDarkClass}`
let css = createStyles(
{
selector: ":root",
styles: {
"--ddln-neutral-100": "#151515",
"--ddln-neutral-200": "#212121",
"--ddln-neutral-300": "#292929",
"--ddln-link": "#65a9d7",
"--ddln-link-dark": "#617f89",
"--ddln-note": "#ced4da",
"--ddln-text": "#ffffff",
},
},
);
/**
* @param {'dark' | 'light'} [theme]
*/
function toggleTheme(theme) {
const dark = typeof theme === 'string' ? theme === 'dark' : undefined
console.log(dark)
document.body.classList.toggle(themeDarkClass, dark)
}
const isLogin = location.href.includes('login/')
if (isLogin) {
// WARNING: cdn.jsdelivr.net not intended for a large number of users.
waitForElement('.btn img[src*="facebook"]').then(el => el.setAttribute("src", "https://cdn.jsdelivr.net/gh/twbs/icons/icons/facebook.svg"))
waitForElement('.btn img[src*="google"]').then(el => el.setAttribute("src", "https://cdn.jsdelivr.net/gh/twbs/icons/icons/google.svg"))
css += createStyles(
{
selector: ".btn img[src*='facebook']",
styles: {
filter: "invert(1)"
}
},
{
selector: ["#page", ".dropdown-menu"],
styles: {
background: "var(--ddln-neutral-100) !important"
}
},
{
selector: [".mform fieldset"],
styles: {
borderColor: "var(--ddln-neutral-100) !important"
}
},
{
selector: ["a", ".btn-link", ".btn-link i"],
styles: {
color: "var(--ddln-link) !important"
}
},
{
selector: [".loginform", ".login-container:not(:has(.loginform))", ".modal-content > *"],
styles: {
background: "var(--ddln-neutral-300) !important",
color: "white"
}
},
{
selector: ".mform fieldset:last-child",
styles: {
borderBottom: "none"
}
},
{
selector: ".btn-block:not(.btn-secondary)",
styles: {
border: "none !important",
color: "white !important",
}
},
{
selector: ".login-heading + .btn",
styles: {
background: "white !important",
color: "black !important"
}
}
);
}
else {
waitForElement('a[href="https://dl.nure.ua/login/index.php"]')
.then(
() => toggleTheme('dark'),
() => {}
)
css += createStyles(
{
parent: themeDarkSelector,
selector: [
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
".h1",
".h2",
".h3",
".h4",
".h5",
".h6",
".path-calendar.maincalendar .calendar-controls .current",
".course-content .single-section .sectionname",
".course-content .single-section .sectionname a",
".course-content .section .sectionname",
".course-content .section .sectionname a"
],
styles: {
color: "white !important",
backgroundColor: 'transparent !important'
}
},
{
parent: themeDarkSelector,
selector: ".content .summarytext > div > div",
styles: {
backgroundColor: "transparent !important"
}
},
{
parent: themeDarkSelector,
selector: ":is(a, a:active):not(.moremenu.navigation *, .qnbutton:not(:hover))",
styles: {
color: "var(--ddln-note)"
}
},
{
parent: themeDarkSelector,
selector: "#page-footer .popover.footer .popover-body .footer-section a",
styles: {
color: "var(--ddln-link)"
}
},
{
selector: ["#page-footer a:not(.btn):not(div)"],
styles: {
color: "var(--ddln-link)"
}
},
{
selector: [".qn-question", ".qn-info", "[role=main] > aside > .card", ".aalink.focus", "a.focus.autolink", ".aalink:focus", "a.autolink:focus", "#page-footer a:not([class]).focus", "#page-footer a:not([class]):focus", ".arrow_link.focus", ".arrow_link:focus", "a:not([class]).focus", "a:not([class]):focus", ".activityinstance > a.focus", ".activityinstance>a:focus"],
styles: {
backgroundColor: "transparent !important",
boxShadow: "none !important"
}
},
{
selector: ['.shadow', '.dropdown-menu', '.popover-region-container', '.section-item', "#topofscroll", ".notification", '.forumpost'],
styles: {
boxShadow: "0 0 35px 0 rgba(0 0 0 / 40%) !important"
}
},
{
parent: themeDarkSelector,
selector: [".popover-region-container", ".popover-region-container > *"],
styles: {
border: "1px solid var(--ddln-neutral-200) !important"
}
},
{
parent: themeDarkSelector,
selector: '.popover-region-container a.see-all-link',
styles: {
display: 'block'
}
},
{
parent: themeDarkSelector,
selector: ['.popover-region-container a.see-all-link > *'],
styles: {
background: "var(--ddln-neutral-300) !important",
border: "1px solid var(--ddln-neutral-200) !important"
}
},
{
parent: themeDarkSelector,
selector: ['.popover-region-toggle::before', '.popover-region-toggle::after'],
styles: {
borderBottom: '10px solid var(--ddln-neutral-200) !important',
}
},
{
parent: themeDarkSelector,
selector: ["div #page-content .dashboard-card", '.course-section .section-item', '.forumpost', '.btn.btn-icon.icons-collapse-expand', '.activity', '.btn.btn-icon:hover, .btn.btn-icon:focus'],
styles: {
borderColor: "var(--ddln-neutral-100) !important",
backgroundColor: "var(--ddln-neutral-200) !important"
}
},
{
selector: [".filemanager .fp-tableview table th > div", ".courseindex-item *"],
styles: {
textShadow: "none",
color: "white"
}
},
{
selector: ".btn.footer-footer",
styles: {
background: "var(--primary)"
}
},
{
parent: themeDarkSelector,
selector: [":not([role=main]) > .nav-tabs .nav-link.active", ".file-picker .fp-content"],
styles: {
background: "transparent"
}
},
{
selector: [".quizreviewsummary"],
styles: {
background: "transparent !important"
}
},
{
parent: [".quizreviewsummary", ".path-grade-report-user"],
selector: ["tr", "th", "td"],
styles: {
background: "transparent !important"
}
},
{
parent: themeDarkSelector,
selector: [".c1", ".drawer", ".block .btn-icon", ".que .info", ".section .activity-item:not(.activityinline)"],
styles: {
backgroundColor: "var(--ddln-neutral-200) !important"
}
},
{
parent: themeDarkSelector,
selector: [".fp-viewbar:not(.disabled) a.checked", ".block .btn-icon:hover", ".c0"],
styles: {
backgroundColor: "var(--ddln-neutral-100) !important"
}
},
{
parent: themeDarkSelector,
selector: [":is(table.attlist, .card-text:has(> a[href*=attendance])) :is(.c0, .c1)"],
styles: {
backgroundColor: "transparent !important"
}
},
{
parent: themeDarkSelector,
selector: ["#topofscroll"],
styles: {
background: "var(--ddln-neutral-300) !important",
padding: "24px 15px !important",
boxShadow: "0 0 35px 0 rgba(0 0 0 / 40%) !important"
}
},
{
parent: themeDarkSelector,
selector: [".user-report-container", ".description .course-description-item", ".nav-item > .nav-link:hover", ".forumnodiscuss", ".custom-select", ".formulation", ".drawer-primary .drawercontent .list-group .list-group-item"],
styles: {
background: "var(--ddln-neutral-100) !important",
color: "white !important"
}
},
{
parent: themeDarkSelector,
selector: [".popover-body > *", ".list-group-item", "[data-region=right-hand-drawer].drawer .footer-container"],
styles: {
background: "var(--ddln-neutral-300) !important",
color: "white !important"
}
},
{
parent: themeDarkSelector,
selector: ".activity-header",
styles: {
background: "var(--ddln-neutral-300) !important",
margin: "0 !important"
}
},
{
parent: themeDarkSelector,
selector: [".btn-secondary:focus"],
styles: {
background: "black !important"
}
},
{
parent: themeDarkSelector,
selector: [".answer > *:has([type=radio][checked=checked])", "#page-wrapper", "table tr.grouper td", ".generaltable:not(.quizreviewsummary) tbody tr:nth-of-type(even)", ".activity-add", ".block-add", ".dropdown-menu", ".notification", ".bg-light", ".bg-white", "[role=main] .icons-collapse-expand:hover", "[role=main] .icons-collapse-expand:focus", ".progress"],
styles: {
background: "var(--ddln-neutral-100) !important"
}
},
{
selector: ".fp-iconview .fp-filename-field",
styles: {
position: "relative !important",
height: "fit-content !important"
}
},
{
selector: ".fp-iconview .fp-filename-field > *",
styles: {
background: "none !important",
overflow: "visible",
textWrap: "pretty"
}
},
{
selector: ".filemanager .fp-content",
styles: {
maxHeight: "none !important",
height: "fit-content"
}
},
{
parent: themeDarkSelector,
selector: [".modal-content", ".filemanager .fp-tableview table th", ".filemanager .fp-tableview table td", "#region-main", ".qtype_essay_response.readonly", "button.carousel-navigation-link:hover", ".course-description-item.summarytext > * > * > *", ".moodle-dialogue-base .moodle-dialogue-wrap", ".moremenu .nav-link:hover", ".moremenu .nav-link:focus", ".forumpost.unread *", ".simplesearchform .btn-submit"],
styles: {
background: "var(--ddln-neutral-300) !important"
}
},
{
parent: themeDarkSelector,
selector: ["#region-main:first-child"],
styles: {
marginTop: "0",
}
},
{
parent: themeDarkSelector,
selector: [".maincalendar .calendarmonth .clickable:hover", ".page-link", ".attbtn"],
styles: {
background: "var(--ddln-neutral-100) !important",
border: "1px solid black !important"
}
},
{
parent: themeDarkSelector,
selector: [".activity-item .activity-dates"],
styles: {
color: "var(--ddln-note)"
}
},
{
parent: themeDarkSelector,
selector: [".text-dark"],
styles: {
color: "var(--ddln-link-dark) !important"
}
},
{
parent: themeDarkSelector,
selector: [".activity-item .activity-completion button.btn", ".activity-item .activity-completion a[role=\"button\"].btn"],
styles: {
backgroundColor: "transparent",
border: "1px solid var(--ddln-neutral-100)",
color: "var(--ddln-note)",
padding: "4px 8px",
filter: "none"
}
},
{
parent: themeDarkSelector,
selector: [".fp-navbar", ".que .info", ".modal-content > *", ".activity-item .activity-completion button.btn:hover", ".activity-item .activity-completion a[role=\"button\"].btn:hover"],
styles: {
borderColor: "var(--ddln-neutral-100) !important"
}
},
{
selector: "td.selected",
styles: {
backgroundColor: "var(--success) !important"
}
},
{
selector: ".outcome.clearfix",
styles: {
backgroundColor: "#00ff000f !important",
color: "var(--success) !important"
}
},
{
parent: themeDarkSelector,
selector: [".generaltable td.submissionstatussubmitted", ".generaltable td.earlysubmission", ".generaltable td.submissiongraded"],
styles: {
backgroundColor: "transparent !important",
color: "var(--success) !important"
}
},
{
parent: themeDarkSelector,
selector: [".generaltable td.submissionnotgraded", ".generaltable td.submissionstatusdraft"],
styles: {
backgroundColor: "transparent !important",
color: "var(--danger) !important"
}
},
{
selector: ".navigation .nav-link.active",
styles: {
borderColor: "black !important"
}
},
{
parent: themeDarkSelector,
selector: ".navigation .nav-link.active",
styles: {
borderColor: "white !important"
}
},
{
parent: themeDarkSelector,
selector: [".dropdown-divider", ".nav-tabs", ".bg-light"],
styles: {
borderColor: "black !important"
}
},
{
parent: themeDarkSelector,
selector: [".navbar.fixed-top .divider"],
styles: {
borderColor: "black !important",
backgroundColor: "transparent"
}
},
{
parent: themeDarkSelector,
selector: [".section .activity-item:not(.activityinline)", ".activity-item .activity-afterlink", ".activity-item .activity-altcontent.activity-description", ".filemanager .fp-tableview table th", ".mt-0", ".border", ".activity-navigation .larrow", ".activity-navigation .rarrow", ".course-summaryitem", ".course-section", ".activity-information .activity-dates", ".moodle-dialogue-base .moodle-dialogue-wrap > *", ".moodle-dialogue-base .moodle-dialogue-wrap", ".mform fieldset", ".qnbutton", ".completion-info", ".forumpost.unread .row.header"],
styles: {
borderColor: "var(--ddln-neutral-100) !important"
}
},
{
selector: ["table th", "table td"],
styles: {
borderColor: "var(--ddln-neutral-300) !important"
}
},
{
selector: [".fp-iconview .fp-thumbnail", ".nav-tabs .nav-link", ".nav-tabs .nav-link:hover", ".quizreviewsummary tr > *"],
styles: {
border: "none !important"
}
},
{
parent: themeDarkSelector,
selector: ["#quiz-timer-wrapper #quiz-timer", ".btn-secondary", ".btn-secondary:hover"],
styles: {
border: "none",
backgroundColor: "var(--ddln-neutral-200)",
color: "white"
}
},
{
selector: [".border"],
styles: {
borderRadius: "10px"
}
},
{
parent: themeDarkSelector,
selector: ["table tr:hover", "table tr:hover td", ".submissionnotgraded"],
styles: {
color: "var(--ddln-link-dark) !important",
}
},
{
parent: themeDarkSelector,
selector: [".primary-navigation .navigation .nav-link", ".navbar .popover-region-toggle .icon::before", "pre", "a.courseindex-link"],
styles: {
color: "var(--ddln-note) !important"
}
},
{
parent: themeDarkSelector,
selector: ['.moremenu .dropdown-item.active', "a.nav-link.active", "a.nav-link.active:hover", ".primary-navigation .navigation .nav-link.active:hover", ".text-body", "#page-footer .column-left a.btn", ".contact p.role", ".block-cards span.categoryname", ".navbar-nav .show>.nav-link", ".navbar-nav .active>.nav-link", ".navbar-nav .nav-link.show", ".navbar-nav .nav-link.active", ".submenu .header"],
styles: {
color: "white !important"
}
},
{
parent: themeDarkSelector,
selector: [".fp-iconview .fp-thumbnail > img", ".fp-icon img", "img.req", ".block .btn-icon .fa-ellipsis-v::before", ".dropdown-menu .icon", ".ygtvcell .icon", ".moove-darkmode .gradeitemheader .icon", ".moove-darkmode .navbar-light .navbar-toggler", ".moove-darkmode .notification-image", ".moove-darkmode nav.fixed-top .icon:not([role=popover] *):not(.popover-region-header-actions *)", ".moove-darkmode [role=navigation] .icon", ".moove-darkmode .drawer.drawer-left .drawertoggle", ".moove-darkmode .courseindex-item:not(.pageitem):hover .icon", ".btn.drawertoggle"],
styles: {
filter: "invert(1)"
}
},
{
selector: ["[role=main] .icons-collapse-expand i", ".btn-footer-popover i"],
styles: {
filter: "invert(0) !important"
}
},
{
parent: themeDarkSelector,
selector: ["#mod_quiz_navblock a.qnbutton", "#page.drawers::-webkit-scrollbar-track", ".course-section .availabilityinfo"],
styles: {
background: "var(--ddln-neutral-100) !important"
}
},
{
parent: themeDarkSelector,
selector: "#page.drawers::-webkit-scrollbar-thumb",
styles: {
borderColor: "var(--ddln-neutral-100) !important"
}
},
{
parent: themeDarkSelector,
selector: ".drawercontent::-webkit-scrollbar-track",
styles: {
background: "var(--ddln-neutral-300) !important"
}
},
{
parent: themeDarkSelector,
selector: ".drawercontent::-webkit-scrollbar-thumb",
styles: {
borderColor: "var(--ddln-neutral-300) !important"
}
},
{
selector: [".pagelayout-incourse #region-main", ".drawer.drawer-right.show"],
styles: {
padding: "0 !important"
}
},
{
parent: themeDarkSelector,
selector: ["#theme_boost-drawers-courseindex"],
styles: {
padding: "0 !important"
}
},
{
selector: ["[role=main] > .nav-tabs", "#region-main", "[role=main] .alert", "#user-notifications .alert"],
styles: {
marginTop: "25px"
}
},
{
selector: ["#maincontent", ".content-item-container .view-more", ".course-listitem .pl-1.pr-1:first-child"],
styles: {
display: "none !important"
}
},
{
parent: themeDarkSelector,
selector: ".btn-outline-secondary",
styles: {
padding: "6px 12px"
}
},
{
selector: "notifications",
styles: {
padding: "6px 12px"
}
},
{
selector: ".section-item:has(ul.section:not(.d-block)):not(:has([data-for=sectioninfo]:has(:not(.section_availability))))",
styles: {
opacity: '0.2',
}
},
{
selector: '.row .curdatecontrols :is(a, form button)',
styles: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: '0 3px !important',
background: 'var(--ddln-neutral-100)',
minWidth: '25px',
height: '30px',
textDecoration: 'none !important',
borderRadius: '.5rem',
textAlign: 'center',
color: 'var(--ddln-text)',
border: 'none',
}
}
);
function changeElementSelfStyles(darkmode) {
let selector = '.fixed-top a:not([id]).nav-link';
for (const ftnav of Array.from(document.body.querySelectorAll(selector))) {
if (!(ftnav instanceof HTMLElement)) return;
ftnav.style.color = `${darkmode ? 'white' : 'black'} !important`;
}
}
changeElementSelfStyles(document.body.classList.contains(themeDarkClass));
waitForElement('toggle-darkmode-input').then(themeToggleButton => themeToggleButton.addEventListener(
'click',
() => changeElementSelfStyles(!document.body.classList.contains(themeDarkClass))
));
}
// @ts-ignore
GM_addStyle(css)
waitForElement('[title="We stand with Ukraine"]').then(uaflag => uaflag.remove())