diff --git a/css/all.css b/css/all.css index 658056b8..93801372 100644 --- a/css/all.css +++ b/css/all.css @@ -3,6 +3,7 @@ --primary-color: hsl(var(--color-hue), 50%, 50%); --background-color: hsl(var(--color-hue), 60%, 30%); --hover-color: hsl(var(--color-hue), 55%, 40%); + --link-color: var(--hover-color); --border-color: hsl(var(--color-hue), 60%, 25%); --cursor: auto; --background-url: none; @@ -54,7 +55,7 @@ footer button { } footer._2T2dA { - background-color: rgb(51, 51, 51) !important; + background-color: var(--primary-color) !important; } /* Logo */ @@ -356,6 +357,7 @@ section.sgy-card .sgy-card-lens img.injected-course-icon { background-color: var(--hover-color) !important; } +.submit-span-wrapper, .submit-span-wrapper input[type=button], .submit-span-wrapper input[type=submit] { height: 25px !important; @@ -584,8 +586,8 @@ the selector matches inside notifications in the new notifs dropdown } .splus-logo-inline { - height: 22px; - filter: brightness(0.4); + height: 18px; + color: currentColor; vertical-align: middle; padding-right: 3px; } @@ -607,8 +609,9 @@ body #grading-group- span.ajax-post-comment, span[role=button], .period-row .title, .category-row .title, -._2mWUT a { - color: var(--hover-color) !important; +._2mWUT a, +div._3U8Br { + color: var(--link-color) !important; } body #nav ul li a:hover, @@ -631,7 +634,7 @@ body .search-toggle:hover, body #primary-settings .unfold:hover, ul.tabs li a.active, #nav ul li a:hover { - background-color: var(--hover-color) !important; + background-color: var(--link-color) !important; color: white !important; } @@ -648,4 +651,61 @@ div.courses-left-menu, .portfolio-list a.btn, a._3_bfp { color: white !important; +} + +.setting-highlight { + color: lightyellow !important; +} + +.course-dashboard section.sgy-card img.injected-course-icon { + height: 80% !important; +} + +.splus-beta-container { + position: fixed; + left: 3px; + top: 12px; + z-index: 9999; + color: white !important; + border: 2px solid white; + border-radius: 10px; + background-color: dodgerblue; + padding: 5px 8px; + width: 10px; + height: 20px; +} + +.splus-beta-container:hover { + width: unset; + height: unset; +} + +.splus-beta-container h3 { + color: white !important; + border-bottom: 1px solid white !important; +} + +.splus-beta-tag { + cursor: pointer; + font-size: 16px; + font-weight: bold; +} + +.splus-beta-container:hover .splus-beta-tag::after { + content: "eta Enabled"; +} + +.splus-beta-container div { + display: none; +} + +.splus-beta-container:hover div { + display: block; + padding-top: 5px; +} + +.splus-beta-container div input[type=checkbox] { + vertical-align: middle; + float: left; + margin-right: 10px; } \ No newline at end of file diff --git a/css/grades.css b/css/grades.css index 81ee1460..c4cb6387 100644 --- a/css/grades.css +++ b/css/grades.css @@ -218,12 +218,11 @@ input#enable-modify { letter-spacing:normal; } -img.splus-coursegradebox-taint { - width: 1em; - height: 1em; +svg.splus-coursegradebox-taint { + width: 1.2em; + height: 1.2em; vertical-align: middle; - filter: brightness(0.0625); /* 1/16; corresponds with Schoology's #111111 */ - padding-right: 0.1em; + padding-right: 0.2em; } .splus-weighted-gradebook-indicator { diff --git a/css/modern.css b/css/modern.css new file mode 100644 index 00000000..6e7e9172 --- /dev/null +++ b/css/modern.css @@ -0,0 +1,1035 @@ +:root { + --primary: #36393F; + --accent: #2F3136; + --secondary: #202225; + --text: #DCDDDE; + --contrast-text: #EEEEEE; + --muted-text: #72767D; + --contrast-border: #DCDDDE; + --input: #40444B; + --error: #F44336; + --highlight: rgba(184, 134, 11, 0.2); + --active: rgba(0, 255, 255, 0.1); + --grades: #8BC34A; + --border-radius: 5px; + --border-size: 1px; + --padding: 10px; + --theme-is-dark: 1; +} + +:root[dark=false] { + --primary: #EEEEEE; + --accent: white; + --secondary: #DDD; + --text: #2A2A2A; + --contrast-text: white; + --muted-text: #677583; + --contrast-border: #BABABA; + --input: #CCCCCC; + --error: #F44336; + --highlight: rgba(255, 183, 2, 0.2); + --active: #98d4e4; + --grades: #009400; + --border-radius: 5px; + --border-size: 1px; + --padding: 10px; + --theme-is-dark: 0; +} + +:root[test=true] { + --primary: black; + --accent: black; + --secondary: black; + + --text: black; + --contrast-text: black; + --muted-text: black; + + --contrast-border: black; + --input: black; + --error: black; + --highlight: black; + --active: black; + --grades: black; + --border-radius: 5px; + --border-size: 1px; + --padding: 10px; + + --hover-color: black !important; +} + +:root[test=true][test-mode=crazy] { + --primary: magenta; + --accent: purple; + --secondary: maroon; + + --text: yellow; + --contrast-text: mediumspringgreen; + --muted-text: orange; + + --contrast-border: gold; + --input: blue; + --error: red; + --highlight: rgba(0, 255, 0, 0.3); + --active: rgba(0, 0, 255, 0.3); + --grades: aqua; + + --hover-color: lime !important; +} + +/* General */ + +h1, +h2, +h3, +h4, +h5, +h6, +p { + color: var(--text) !important; +} + +textarea, +select, +input[type=text] { + background-color: var(--input) !important; + color: var(--text) !important; + border: none !important; + border-radius: var(--border-radius) !important; +} + +ul.context-menu-list, +ul.context-menu-list li.context-menu-item { + background-color: var(--secondary) !important; + color: var(--text) !important; + border-color: var(--accent) !important; +} + +ul.context-menu-list li.context-menu-item:hover { + background-color: var(--active) !important; +} + +#body { + background-color: var(--primary) !important; +} + +#main-content-wrapper { + background-color: var(--accent) !important; + color: var(--text) !important; + border: none !important; + border-bottom-left-radius: var(--border-radius) !important; + border-bottom-right-radius: var(--border-radius) !important; +} + +#right-column-inner>div:not(:empty) { + background-color: var(--secondary) !important; + border: none !important; + border-radius: var(--border-radius) !important; + padding: var(--padding) !important; +} + +#center-top { + background: unset !important; + background-color: var(--accent) !important; + color: var(--text) !important; + border: none !important; +} + +body a.link-btn, +body button.link-btn { + box-shadow: none !important; + background: none !important; + background-color: var(--secondary) !important; + color: var(--text) !important; + border: none !important; + border-radius: var(--border-radius) !important; +} + +.inline-popup-wrapper { + background-color: var(--secondary) !important; + color: var(--text) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; +} + +.inline-popup-wrapper .arrow-top { + display: none !important; +} + +.splus-modal-title, +.submit-span-wrapper, +.submit-span-wrapper input[type="button"], +.submit-span-wrapper input[type="submit"], +:not(.submit-span-wrapper)>input[type="button"], +:not(.submit-span-wrapper)>input[type="submit"], +footer li a, +header li a, +.splus-modal-footer-text, +.splus-modal-footer-text a, +body a.link-btn.active, +div.courses-left-menu, +.portfolio-list a.btn, +a._3_bfp, +footer, +footer button, +.Header-header-button-1EE8Y, +[class*="Header-header-drop-menu-item-"], +[class*="Header-header-drop-menu-"] li a *, +.Header-header-button-active-GnvKh, +.LGaPf svg { + color: var(--contrast-text) !important; +} + +.close { + color: var(--contrast-text) !important; + opacity: 0.8 !important; +} + +.close:hover, +.close:focus { + opacity: 1 !important; + color: var(--contrast-text) !important; +} + +/* Schoology Popups */ +.popups-box .popups-body, +#popups-loading div { + background-color: var(--primary) !important; + color: var(--text) !important; + border: none !important; +} + +.popups-box .submit-buttons { + background-color: var(--accent) !important; + border-top: none !important; +} + +.popups-box .popups-title { + background-color: var(--secondary) !important; + color: var(--text) !important; + border: none !important; +} + +.popups-close a { + background-position-y: calc(-80px - (20px * var(--theme-is-dark))) !important; +} + +.likers li:not(.last) { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +/* Courses and Groups Dropdown */ +.splus-courses-navbar-button div[role=menu], +.splus-groups-navbar-button div[role=menu] { + background-color: var(--accent) !important; +} + +.splus-coursesdropdown-reorder-btn { + filter: invert(var(--theme-is-dark)) !important; +} + +.splus-courses-navbar-button article, +.splus-courses-navbar-button article a, +.splus-groups-navbar-button article, +.splus-groups-navbar-button article a { + border: var(--border-size) solid transparent !important; + outline: none !important; +} + +.splus-courses-navbar-button article a:hover, +.splus-groups-navbar-button article a:hover { + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; +} + +.Card-card-image-uV6Bu { + border-top-left-radius: var(--border-radius) !important; + border-top-right-radius: var(--border-radius) !important; +} + +.Card-card-data-17m6S, +.Card-card-data-17m6S div { + border-bottom-left-radius: var(--border-radius) !important; + border-bottom-right-radius: var(--border-radius) !important; +} + +.splus-courses-navbar-button article a div, +.splus-groups-navbar-button article a div { + background-color: var(--primary) !important; +} + +.splus-courses-navbar-button article a div div._1wP6w, +.splus-groups-navbar-button article a div div._1wP6w { + color: var(--text) !important; +} + +.splus-courses-navbar-button article a div div._2wOCj, +.splus-groups-navbar-button article a div div._2wOCj { + color: var(--muted-text) !important; +} + +header div.Je0RK button._1SIMq { + background-color: var(--secondary) !important; + color: var(--text) !important; + border-radius: var(--border-radius) !important; +} + +._1DD87, +._3gfrT:focus:not(:active), +.oUq3j:hover:not(:active) { + border: var(--border-size) solid var(--contrast-border) !important; +} + +/* Navbar menus */ +div.les2- { + background-color: var(--secondary) !important; +} + +div.les2- ._3skcp { + border-color: var(--contrast-border) !important; +} + +div.les2- ._1wP6w { + color: var(--text) !important; +} + +div.les2- ._2wOCj { + color: var(--muted-text) !important; +} + +.util-hover-background-color-cloud-grey-wHghL:hover { + background-color: var(--active) !important; +} + +._33zXx { + background-color: var(--text) !important; +} + +div.les2- h3 { + color: var(--text) !important; +} + +/* Modal Red Color */ +.close-button, +.restore-defaults { + color: var(--error) !important; +} + +.setting-highlight { + background-color: var(--highlight) !important; +} + +/* Home Page */ +[page^="/home"] #center div#main, +[page^="/home"] #main-inner, +[page^="/home"] #main-content-wrapper, +[page="/"] #center div#main, +[page="/"] #main-inner, +[page="/"] #main-content-wrapper, +.splus-modal-body { + background-color: var(--primary) !important; + color: var(--text) !important; +} + +[page^="/home"] #right-column-inner div, +[page^="/home"] #home-feed-container, +[page="/"] #right-column-inner div, +[page="/"] #home-feed-container { + background-color: var(--accent) !important; + color: var(--text) !important; + border-radius: var(--border-radius) !important; +} + +.date-header h4 span, +.s-poll-option-title, +.s-like-sentence { + color: var(--text) !important; +} + +.s-polls-poll-option, +#edge-filters-menu { + background: none !important; + background-color: var(--secondary) !important; + color: var(--text) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; +} + +#edge-filters { + background: none !important; + border: none !important; +} + +#edge-filters-btn, +.feed-comments { + background-position-y: calc(-576px - 18px * var(--theme-is-dark)) !important; + background-color: var(--secondary) !important; + color: var(--text) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; + opacity: unset !important; +} + +#edge-filters-menu .edge-filter-option { + background-position: 0 calc(-237px - 20px * var(--theme-is-dark)) !important; +} + +#edge-filters-menu .edge-filter-option:hover, +#edge-filters-menu .edge-filter-option.active:hover { + background-color: var(--active) !important; + color: var(--text) !important; +} + +.gray, +.upcoming-time { + color: var(--muted-text) !important; +} + +img.splus-logo-inline { + filter: brightness(var(--theme-is-dark)) !important; +} + +.splus-broadcast-post { + background-color: var(--active) !important; +} + +.theme-2016 .date-header h4, +#home-feed-container #smart-box { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.view-file-popup, +.view-btn-disabled, +.edit-external-tool-attachment { + border-left: var(--border-size) solid var(--contrast-border) !important; +} + +.sgy-tabbed-navigation { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.sgy-tabbed-navigation li.active { + border-bottom: 5px solid var(--contrast-border) !important; +} + +/* Grades Page */ +.gradebook-course.hierarchical-grading-report .period-row .grade-column, +.gradebook-course.hierarchical-grading-report .category-row .grade-column, +.gradebook-course.hierarchical-grading-report .item-row .grade-column, +.grade-active-color, +.awarded-grade span { + color: var(--grades) !important; +} + +.due-date, +.gradebook-course.hierarchical-grading-report .grade-column .max-grade, +.percentage-contrib, +span.comment, +.grade-none-color, +.course-grade-text, +.total-points-wrapper *, +.percentage-grade, +.no-grade { + color: var(--text) !important; +} + +div.summary-course { + background-color: var(--secondary) !important; + color: var(--text) !important; + border: none !important; + border-radius: var(--border-radius) !important; +} + +.grade-edit-indicator { + filter: grayscale(var(--theme-is-dark)) invert(var(--theme-is-dark)) !important; +} + +.gradebook-course.hierarchical-grading-report .item-row .td-content-wrapper { + border-top: var(--border-size) dotted var(--contrast-border) !important; +} + +.gradebook-course.hierarchical-grading-report .period-row .td-content-wrapper, +.gradebook-course.hierarchical-grading-report .final-row .td-content-wrapper, +.gradebook-course.hierarchical-grading-report .td-content-wrapper { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +.item-row.added-fake-assignment { + background-color: var(--highlight) !important; +} + +.splus-grade-help-btn .icon-help { + background-position: calc(0px - 22px * var(--theme-is-dark)) -127px !important; +} + +.gradebook-course.hierarchical-grading-report .childrenCollapsed .title-column:hover .expandable-icon-grading-report { + position: absolute !important; + clip: rect(calc(15px - (15px * var(--theme-is-dark))), calc(30px - (15px * var(--theme-is-dark))), calc(30px - (15px * var(--theme-is-dark))), 0) !important; + top: calc(0px + (16px * var(--theme-is-dark))) !important; + left: -20px !important; + opacity: 1 !important; +} + +.gradebook-course.hierarchical-grading-report .childrenCollapsed .title-column .expandable-icon-grading-report { + position: absolute !important; + clip: rect(calc(15px - (15px * var(--theme-is-dark))), calc(30px - (15px * var(--theme-is-dark))), calc(30px - (15px * var(--theme-is-dark))), 0) !important; + top: calc(0px + (16px * var(--theme-is-dark))) !important; + left: -20px !important; + opacity: 0.8 !important; +} + +.gradebook-course.hierarchical-grading-report .title-column .expandable-icon-grading-report { + position: absolute !important; + clip: rect(calc(46px - (11px * var(--theme-is-dark))), calc(60px - (45px * var(--theme-is-dark))), calc(80px - (30px * var(--theme-is-dark))), 0) !important; + top: calc(-32px + (16px * var(--theme-is-dark))) !important; + left: -20px !important; + opacity: 0.8 !important; +} + +.gradebook-course.hierarchical-grading-report .title-column:hover .expandable-icon-grading-report { + position: absolute !important; + clip: rect(calc(46px - (11px * var(--theme-is-dark))), calc(60px - (45px * var(--theme-is-dark))), calc(80px - (30px * var(--theme-is-dark))), 0) !important; + top: calc(-32px + (16px * var(--theme-is-dark))) !important; + left: -20px !important; + opacity: 1 !important; +} + +.empty.grades-empty { + color: var(--muted-text) !important; +} + +.download-grade-wrapper a.link-btn { + background-color: var(--primary) !important; +} + +#past-selector .item-list a.link-btn.active { + background-color: var(--active) !important; +} + +body ul.primary li.active a, +body ul.primary li.active a:hover, +body ul.primary li a, +body ul.primary li a:hover, +body ul.primary li a:visited, +body ul.primary { + border-color: var(--contrast-border) !important; + border-width: var(--border-size) !important; +} + +.gradebook-course, .attendance-course { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +[page*="/student_attendance"] table thead th { + border-color: var(--contrast-border) !important; + border-width: var(--border-size) 0 !important; +} + +.attendance-course-attendance table th, +.attendance-course-attendance table td { + border: var(--border-size) solid var(--contrast-border) !important; +} + +/* Mastery Page */ +#s-js-student-mastery-report-view-content { + background-color: var(--accent) !important; +} + +.s-js-chart-and-pager-area .empty { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +/* Courses Page */ +.course-action-btns, +.group-action-btns { + padding: var(--padding) !important; + border-radius: var(--border-radius) !important; +} + +#secondary-tabs-wrapper { + border-right: none !important; + background-color: var(--accent) !important; +} + +body>div._1f1I3._35u4I.IaH_B.RuZ14.VSOiH._3brnw.S42JQ>div>div { + background-color: var(--primary) !important; +} + +body>div._1f1I3._35u4I.IaH_B.RuZ14.VSOiH._3brnw.S42JQ>div>div button { + filter: grayscale(var(--theme-is-dark)) invert(var(--theme-is-dark)); +} + +body>div._1f1I3._35u4I.IaH_B.RuZ14.VSOiH._3brnw.S42JQ>div>div .Card-card-2rORL { + background-color: var(--accent) !important; + border: none !important; + border-radius: var(--border-radius) !important; +} + +body>div._1f1I3._35u4I.IaH_B.RuZ14.VSOiH._3brnw.S42JQ>div>div div { + color: var(--text) !important; +} + +body>div._1f1I3._35u4I.IaH_B.RuZ14.VSOiH._3brnw.S42JQ>div>div div._2wOCj { + color: var(--muted-text) !important; +} + +body #right-column-inner button.link-btn, +body #right-column-inner a.link-btn { + background-color: var(--primary) !important; +} + +#reorder-ui button.link-btn span { + filter: invert(var(--theme-is-dark)) !important; +} + +.course-list-view #secondary-tabs-wrapper ul { + border-bottom: none !important; +} + +.no-courses { + color: var(--muted-text) !important; +} + +.tabs.secondary li a { + background: var(--secondary) !important; + color: var(--text) !important; + border: none !important; + border-radius: var(--border-radius) !important; +} + +.tabs.secondary li.active a { + background: none !important; + color: var(--text) !important; + background-color: var(--active) !important; + border-radius: var(--border-radius) !important; + border: none !important; +} + +.listing .course-item.list-item, +.courses-listing.mycourses h3 { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +#main .courses-listing.listing { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +/* Members Page */ +.enrollment-search .go-btn { + background-color: inherit !important; +} + +.roster-top { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +body .enrollment-filters span.active, body .grading-groups-list .grading-group.active { + background-color: var(--active) !important; +} + +.enrollment-filters span:hover { + background-color: var(--active) !important; +} + +/* Breadcrumbs */ + +#site-navigation-breadcrumbs nav { + background-color: var(--accent) !important; +} + +#site-navigation-breadcrumbs nav li a, +#site-navigation-breadcrumbs nav li span { + color: var(--text) !important; +} + +/* Resources Page */ +[page^="/resources"] #main-content-wrapper { + background-color: var(--primary) !important; +} + +#library-main { + border-right: none !important; +} + +#library-main iframe { + /* iframe must be white, because we can't change styles within it */ + background-color: white !important; +} + +#library-wrapper { + background-color: var(--accent) !important; + border: none !important; + border-bottom-left-radius: var(--border-radius) !important; + border-bottom-right-radius: var(--border-radius) !important; +} + +#library-wrapper a.active { + background-color: var(--active) !important; +} + +#library-wrapper .library-collections a:hover, +#library-left td:hover { + background-color: var(--active) !important; +} + +#library-search-form-container div { + background-color: var(--secondary) !important; +} + +#library-search-form-container div::before { + display: none !important; +} + +#collection-view-contents .collection-row-empty td { + color: var(--text) !important; +} + +body.library-view #library-main { + border-left: var(--border-size) solid var(--contrast-border) !important; +} + +#collection-toolbar, +#collection-view-contents { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +#collection-view-contents th, +#collection-view-contents td, +#library-left .collections-list-wrapper { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +body.library-view #library-left { + border-right: var(--border-size) solid var(--contrast-border) !important; +} + +#collection-toolbar .action-links-unfold { + box-shadow: none !important; + border: none !important; + background: var(--secondary) !important; + border-radius: var(--border-radius) !important; + color: var(--text) !important; +} + +.action-links-wrapper-expanded .action-links-unfold .action-links-unfold-text { + color: var(--text) !important; +} + +#reorder-collections-btn { + color: var(--text) !important; +} + +#reorder-collections-btn:hover { + background-color: var(--active) !important; + color: var(--text) !important; +} + +/* Profile Page */ +.right-block-big-wrapper { + padding: var(--padding) !important; + border-radius: var(--border-radius) !important; +} + +#sidebar-left #left-nav #menu-s-main ul li a.active { + background-color: var(--accent) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-right: none !important; + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; +} + +th.profile-header { + color: var(--text) !important; +} + +/* Course Page */ +.action-links, +.comment.no-comments, +.materials-filter-wrapper { + background-color: var(--secondary) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; + color: var(--text) !important; +} + +.materials-filter-wrapper .action-links-wrapper .action-links-unfold, +.action-links-wrapper-gearless .action-links-unfold.active, +.action-links-wrapper-gearless .action-links-unfold:active { + color: var(--text) !important; +} + +.action-links .selected { + background-position: 0 calc(-237px - 20px * var(--theme-is-dark)) !important; +} + +body .action-links a:hover { + background-color: var(--active) !important; + color: var(--text) !important; +} + +.materials-top, +#folder-contents-table td, +#right-column h3, +.left-block-wrapper h3 { + border: none !important; + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.s-edge-feed li { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +.s-like-sentence:not(:last-child) { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.pre-fill, +.upcoming-list .empty, +.no-attendance-status-dates { + color: var(--muted-text) !important; +} + +#edit-course-switcher-select-nid-menu { + border: var(--border-size) solid var(--contrast-border) !important; + background-color: var(--secondary); + border-radius: var(--border-radius) !important; +} + +#edit-course-switcher-select-nid-menu .ui-selectmenu-group li a:hover { + color: var(--text) !important; + background-color: var(--active) !important; +} + +#edit-course-switcher-select-nid-button { + border: none !important; + background: none !important; + background-color: var(--secondary) !important; + border-radius: var(--border-radius) !important; +} + +#edit-course-switcher-select-nid-button:not(.ui-state-active) .edit-course-inline-dropdown-arrow { + filter: invert(var(--theme-is-dark)) !important; +} + +.messages.warning { + background: var(--highlight) !important; + color: var(--text) !important; +} + +span#updates-count { + color: var(--text) !important; + background-color: var(--active) !important; +} + +/* User Page */ +.info-tab th, +.info-tab td, +.enrollment-view-wrapper td, +.enrollment-view-wrapper th { + color: var(--muted-text) !important; + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.info-tab .profile-header { + color: var(--text) !important; +} + +.private-profile { + background-color: var(--secondary) !important; + color: var(--text) !important; + border-color: var(--contrast-border) !important; +} + +.private-profile h3 { + border-color: var(--contrast-border) !important; +} + +/* School / Group Page */ +#school-events { + padding: var(--padding) !important; + border-radius: var(--border-radius) !important; +} + +#main { + background-color: var(--accent) !important; +} + +[page^="/school/"] #content-wrapper, +[page^="/school/"] td, +[page^="/group/"] #content-wrapper, +[page^="/group/"] td { + background-color: var(--accent) !important; + color: var(--text) !important; +} + +.left-block dd { + color: var(--text) !important; +} + +.left-block dt { + color: var(--muted-text) !important; +} + +.enrollment-view-wrapper, +.roster-top, +.active-loader { + background-color: var(--accent) !important; +} + +#s-user-realm-profile-notification-setting-form label:hover { + background: none !important; + background-color: var(--active) !important; +} + +#content-left .s-enrollment-realm-actions { + border-top: var(--border-size) solid var(--contrast-border) !important; +} + +/* Course Dashboard */ +.course-dashboard section { + border: none !important; + border-radius: var(--border-radius) !important; +} + +.course-dashboard section.sgy-card, +.course-dashboard .sgy-card-lens { + background-color: var(--accent) !important; + border-radius: var(--border-radius) !important; +} + +.course-dashboard .sgy-card { + border: var(--border-size) solid transparent !important; +} + +.course-dashboard .sgy-card:hover { + border: var(--border-size) solid var(--contrast-border) !important; +} + +.course-dashboard .sgy-card:hover .sgy-card-lens::after { + display: none !important; +} + +.course-dashboard section.sgy-card .sgy-multiline-ellipsis__split-part { + color: var(--text) !important; +} + +.course-dashboard section.sgy-card .sgy-card-subcontext { + color: var(--muted-text) !important; +} + +.course-dashboard .ui-state-highlight { + border: var(--border-size) dashed var(--contrast-border) !important; + background-color: var(--secondary) !important; +} + +/* Search Bar */ +ul.Search-dropdown-3huUv { + border: none !important; + background-color: var(--accent) !important; +} + +.Search-dropdown-3huUv svg { + filter: invert(var(--theme-is-dark)) !important; +} + +.Search-dropdown-3huUv input { + background-color: var(--input) !important; + color: var(--text) !important; + border-bottom: 1px solid transparent !important; +} + +/* Settings Page */ +ul.primary, +.with-tabs #center-top { + background: unset !important; + background-color: var(--secondary) !important; +} + +ul.primary li a { + background: unset !important; + background-color: var(--secondary) !important; + color: var(--text) !important; +} + +ul.primary li.active a, +.email-notify, +fieldset { + background-color: var(--accent) !important; + color: var(--text) !important; +} + +.sticky-header *, +.ui-selectmenu-status { + background-color: var(--secondary) !important; + color: var(--text) !important; +} + +div.cellphone-container { + background-color: var(--secondary) !important; + color: var(--text) !important; + border-radius: var(--border-radius) !important; +} + +#s-user-set-notifications-form thead tr:hover { + background-color: var(--accent) !important; +} + +.ui-selectmenu { + border: none !important; + border-radius: var(--border-radius) !important; + background: none !important; +} + +.ui-selectmenu-menu { + background: var(--secondary) !important; + border: var(--border-size) solid var(--contrast-border) !important; + border-radius: var(--border-radius) !important; +} + +.ui-selectmenu-menu li a { + color: var(--text) !important; +} + +.ui-selectmenu-menu li:hover a, .ui-selectmenu-menu .ui-selectmenu-item-focus a { + background-color: var(--active) !important; +} + +.ui-selectmenu-menu .ui-selectmenu-item-selected a:after { + background-position: 0 calc(-242px - 20px * var(--theme-is-dark)) !important; +} + + +/* Error Page */ +#error-page { + background-color: var(--secondary) !important; + color: var(--text) !important; +} + +/* Calendar */ +.fc-state-highlight { + background: var(--active) !important; +} + +.fc-view-month td:hover { + background-color: var(--highlight) !important; +} + +table.fc-border-separate td { + border: var(--border-size) solid var(--contrast-border) !important; +} + +table.fc-border-separate .fc-widget-header { + border-bottom: var(--border-size) solid var(--contrast-border) !important; +} + +.fc-agenda-slots td, +.fc-agenda-slots th, +body .fc-widget-header, +.fc-agenda-allday th { + border-color: var(--contrast-border) !important; +} + +body .fc-widget-header .fc-agenda-divider-inner { + background: var(--contrast-border) !important; + border-color: var(--contrast-border) !important; +} \ No newline at end of file diff --git a/css/theme-editor.css b/css/theme-editor.css index 58082f3b..91737e80 100644 --- a/css/theme-editor.css +++ b/css/theme-editor.css @@ -3,6 +3,7 @@ --primary-color: hsl(var(--color-hue), 50%, 50%); --background-color: hsl(var(--color-hue), 60%, 30%); --hover-color: hsl(var(--color-hue), 55%, 40%); + --link-color: var(--hover-color); --border-color: hsl(var(--color-hue), 60%, 25%); --cursor: auto; --lausd-visible: block; @@ -490,7 +491,7 @@ input[type=button] { } .tabs>li>a.active { - color: var(--hover-color) !important; + color: var(--link-color) !important; } .tabs>li>a { @@ -498,7 +499,7 @@ input[type=button] { } .tabs>li>a:hover:not(.active) { - color: var(--hover-color) !important; + color: var(--link-color) !important; } .tabs a:focus.active { @@ -651,7 +652,7 @@ textarea#json-output[readonly] { } .setting-link { - color: var(--hover-color); + color: var(--link-color); } .show-lausd { diff --git a/imgs/new-plus-icon.svg b/imgs/new-plus-icon.svg index 8aa361e1..ef403891 100644 --- a/imgs/new-plus-icon.svg +++ b/imgs/new-plus-icon.svg @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/js/all-idle.js b/js/all-idle.js index e3dc81df..3b180040 100644 --- a/js/all-idle.js +++ b/js/all-idle.js @@ -352,7 +352,7 @@ function parseSettingsHash() { if (hashes.length > 2) { setTimeout(() => { location.hash = hashes[2]; - document.getElementById(hashes[2]).parentElement.parentElement.style.backgroundColor = "lightyellow"; + document.getElementById(hashes[2]).parentElement.parentElement.classList.add("setting-highlight"); location.hash = ""; }, 500); } diff --git a/js/all.js b/js/all.js index e88da94d..7f166c64 100644 --- a/js/all.js +++ b/js/all.js @@ -16,12 +16,76 @@ } } +{ + let betaCode = Setting.getValue("beta"); + let betaSection = null; + if (betaCode in beta_tests) { + // Beta Enabled Notice + let betaTag = createElement("span", ["splus-beta-tag", "splus-track-clicks"], { textContent: "β", id: "beta-tag" }); + betaTag.addEventListener("click", event => openModal("beta-modal")); + let betaContainer = createElement("div", ["splus-beta-container"], {}, [betaTag]); + document.body.append(betaContainer); + betaSection = createBetaSection(betaCode); + betaContainer.append(betaSection); + } + + function createBetaSection(name) { + return createElement("div", ["splus-beta-section"], { id: `splus-beta-section-${name}` }, [ + createElement("h3", [], { textContent: name }) + ]); + } + + function createBetaToggleCheckbox(name, onchange, checked = false, nestingLevel = 1) { + return createElement("div", ["splus-beta-toggle"], { style: { paddingLeft: `${(nestingLevel - 1) * 10}px` } }, [ + createElement("label", [], { textContent: name }), + createElement("input", [], { type: "checkbox", checked: checked, onchange: onchange }) + ]); + } + + // Dark Theme Beta + if (betaCode == "darktheme") { + let newThemeSheet = createElement("link", [], { rel: "stylesheet", href: chrome.runtime.getURL("/css/modern.css") }); + document.head.append(newThemeSheet); + document.documentElement.setAttribute("test-mode", "crazy"); + + var darkThemeTheme = Theme.loadFromObject({ + "color": + { + "custom": + { + "background": "#36393f", + "border": "#40444b", + "hover": "#6fa8dc", + "primary": "#202225" + } + }, "logo": + { + "preset": "schoology_plus" + }, + "name": "Dark Theme Test", + "version": 2 + }); + + Theme.apply(darkThemeTheme); + + betaSection.append( + createBetaToggleCheckbox("Enable new theme engine", event => newThemeSheet.disabled = !event.target.checked, true), + createBetaToggleCheckbox("Enable dark theme", event => { + document.documentElement.setAttribute("dark", event.target.checked); + Theme.apply(event.target.checked ? darkThemeTheme : Theme.byName(Setting.getValue("theme"))); + }, true), + createBetaToggleCheckbox("Enable color test", event => document.documentElement.setAttribute("test", event.target.checked)), + createBetaToggleCheckbox("Crazy mode", event => document.documentElement.setAttribute("test-mode", event.target.checked ? "crazy" : "standard"), true, 2) + ); + } +} + // Check Schoology domain { const BLACKLISTED_DOMAINS = ["asset-cdn.schoology.com", "developer.schoology.com", "support.schoology.com", "info.schoology.com", "files-cdn.schoology.com", "status.schoology.com", "ui.schoology.com", "www.schoology.com", "api.schoology.com", "developers.schoology.com", "schoology.com", "support.schoology.com"]; let dd = Setting.getValue("defaultDomain"); - if (dd !== window.location.host && !BLACKLISTED_DOMAINS.includes(window.location.host) && !window.location.host.match(/.*\.apps\.schoology\.com/)) { + if (dd !== window.location.host && !BLACKLISTED_DOMAINS.includes(window.location.host) && !window.location.host.match(/.*[-\.]app\.schoology\.com/)) { Setting.setValue("defaultDomain", window.location.host); let bgColor = document.querySelector("#header header").style.backgroundColor; @@ -371,11 +435,11 @@ document.body.onkeydown = (data) => { document.querySelector("#header > header > nav > ul:nth-child(2)").prepend(createElement("li", ["_24avl", "_3Rh90", "_349XD"], {}, [ createElement( - "a", + "button", ["_1SIMq", "_2kpZl", "_3OAXJ", "_13cCs", "_3_bfp", "_2M5aC", "_24avl", "_3v0y7", "_2s0LQ", "_3ghFm", "_3LeCL", "_31GLY", "_9GDcm", "_1D8fw", "util-height-six-3PHnk", "util-line-height-six-3lFgd", "util-text-decoration-none-1n0lI", "Header-header-button-active-state-3AvBm", "Header-header-button-1EE8Y", "sExtlink-processed"], - { href: "#", onclick: () => openModal("settings-modal") }, + { onclick: () => openModal("settings-modal") }, [ - createElement("img", ["Header-two-point-two-ONgMZ", "Header-two-point-two-ONgMZ", "_1I3mg"], { src: chrome.runtime.getURL("imgs/new-plus-icon.svg") }) + createSvgLogo("_3ESp2", "dlCBz", "_1I3mg", "fjQuT", "uQOmx") ] ) ])); @@ -858,4 +922,83 @@ let siteNavigationTileHelpers = { docObserver.observe(document.body, { childList: true, subtree: true }); })(); +async function createQuickAccess() { + let rightCol = document.getElementById("right-column-inner"); + let linkWrap; + + let wrapper = createElement("div", ["quick-access-wrapper"], {}, [ + createElement("h3", ["h3-med"], { title: "Added by Schoology Plus" }, [ + createSvgLogo("splus-logo-inline"), + // createElement("img", ["splus-logo-inline"], { src: chrome.runtime.getURL("imgs/plus-icon.png"), title: "Provided by Schoology Plus" }), + createElement("span", [], { textContent: "Quick Access" }), + createElement("a", ["quick-right-link", "splus-track-clicks"], { id: "quick-access-splus-settings", textContent: "Settings", href: "#splus-settings#setting-input-quickAccessVisibility" }) + ]), + createElement("div", ["date-header", "first"], {}, [ + createElement("h4", [], { textContent: "Pages" }) + ]), + (linkWrap = createElement("div", ["quick-link-wrapper"])) + ]); + + const PAGES = [ + { textContent: "Grade Report", href: "/grades/grades", id: "quick-access-grades" }, + { textContent: "Courses", href: "/courses", id: "quick-access-courses" }, + { textContent: "Mastery", href: "/mastery", id: "quick-access-mastery" }, + { textContent: "Groups", href: "/groups", id: "quick-access-groups" }, + { textContent: "Messages", href: "/messages", id: "quick-access-messages" }, + ]; + + for (let page of PAGES) { + let a = linkWrap.appendChild(createElement("a", ["quick-link", "splus-track-clicks"], page)); + a.dataset.splusTrackingLabel = "Quick Access"; + } + + wrapper.appendChild( + createElement("div", ["date-header"], {}, [ + createElement("h4", [], {}, [ + createElement("span", [], { textContent: "Courses" }), + createElement("a", ["quick-right-link", "splus-track-clicks"], { id: "quick-access-reorder", textContent: "Reorder", href: "/courses?reorder" }) + ]) + ]) + ); + + let sectionsList = (await fetchApiJson(`users/${getUserId()}/sections`)).section; + + if (!sectionsList || sectionsList.length == 0) { + wrapper.appendChild(createElement("p", ["quick-access-no-courses"], { textContent: "No courses found" })); + } else { + let courseOptionsButton; + let iconImage; + for (let section of sectionsList) { + wrapper.appendChild(createElement("div", ["quick-access-course"], {}, [ + (iconImage = createElement("div", ["splus-course-icon"], { dataset: { courseTitle: `${section.course_title}: ${section.section_title}` } })), + createElement("a", ["splus-track-clicks", "quick-course-link"], { textContent: `${section.course_title}: ${section.section_title}`, href: `/course/${section.id}`, dataset: { splusTrackingTarget: "quick-access-course-link", splusTrackingLabel: "Quick Access" } }), + createElement("div", ["icons-container"], {}, [ + createElement("a", ["icon", "icon-grades", "splus-track-clicks"], { href: `/course/${section.id}/student_grades`, title: "Grades", dataset: { splusTrackingTarget: "quick-access-grades-link", splusTrackingLabel: "Quick Access" } }), + createElement("a", ["icon", "icon-mastery", "splus-track-clicks"], { href: `/course/${section.id}/student_mastery`, title: "Mastery", dataset: { splusTrackingTarget: "quick-access-mastery-link", splusTrackingLabel: "Quick Access" } }), + (courseOptionsButton = createElement("a", ["icon", "icon-settings", "splus-track-clicks"], { href: "#", dataset: { splusTrackingTarget: "quick-access-settings-link", splusTrackingLabel: "Quick Access" } })) + ]) + ])); + + iconImage.style.backgroundImage = `url(${chrome.runtime.getURL("imgs/fallback-course-icon.svg")})`; + + courseOptionsButton.addEventListener("click", () => openModal("course-settings-modal", { + courseId: section.id, + courseName: `${section.course_title}: ${section.section_title}` + })); + } + } + + switch (Setting.getValue("quickAccessVisibility")) { + case "belowOverdue": + rightCol.querySelector(".overdue-submissions").insertAdjacentElement("afterend", wrapper); + break; + case "bottom": + rightCol.append(wrapper); + break; + default: + rightCol.prepend(wrapper); + break; + } +} + Logger.log("Finished loading all.js"); \ No newline at end of file diff --git a/js/course.js b/js/course.js index 41c82459..99724536 100644 --- a/js/course.js +++ b/js/course.js @@ -4,7 +4,8 @@ let courseSettingsCourseName; let sidebar = document.querySelector(".course-info-wrapper dl"); if (sidebar) { let button = createButton("splus-course-options", "Course Options"); - let img = createElement("img", [], { src: chrome.runtime.getURL("imgs/plus-icon.png"), width: 19, style: { verticalAlign: "middle", paddingLeft: "4px" } }); + let img = createSvgLogo(); + Object.assign(img.style, { verticalAlign: "middle", paddingLeft: "4px", width: "18px" }); button.prepend(img); button.querySelector("input").style.paddingLeft = "4px"; button.style.cursor = "pointer"; diff --git a/js/dashboard.js b/js/dashboard.js new file mode 100644 index 00000000..977f23e5 --- /dev/null +++ b/js/dashboard.js @@ -0,0 +1 @@ +createQuickAccess(); \ No newline at end of file diff --git a/js/grades.js b/js/grades.js index 306c6bc9..56979c59 100644 --- a/js/grades.js +++ b/js/grades.js @@ -427,7 +427,7 @@ var fetchQueue = []; // we put our tweaks here in the first place because it makes sense in the UI, and because it doesn't change with grade edits // yet we want to be clear this is unofficial // TODO discuss potentially better alternatives to either this particular or any img in general for making this clarification - return createElement("img", ["splus-coursegradebox-taint"], { src: chrome.runtime.getURL("imgs/plus-icon.png"), title: "Predicted by Schoology Plus" }); + return createSvgLogo("splus-coursegradebox-taint"); } // points needed for next highest grade @@ -1011,18 +1011,60 @@ var fetchQueue = []; noGrade.insertAdjacentElement("afterend", maxGrade); let f = async () => { - Logger.log(`Fetching max points for (nonentered) assignment ${assignment.dataset.id.substr(2)}`); - let response = await fetchApi(`users/${getUserId()}/grades?section_id=${courseId}`); - if (!response.ok) { - throw { status: response.status, error: response.statusText }; + let domAssignId = assignment.dataset.id.substr(2); + Logger.log(`Fetching max points for (nonentered) assignment ${domAssignId}`); + + let response = null; + let firstTryError = null; + + try { + response = await fetchApi(`sections/${courseId}/assignments/${domAssignId}`); + } catch (err) { + firstTryError = err; + } + + if (response && !response.ok) { + firstTryError = { status: response.status, error: response.statusText }; + } else if (response) { + try { + let json = await response.json(); + + if (json && json.max_points !== undefined) { + // success case + // note; even if maxGrade is removed from the DOM, this will still work + maxGrade.textContent = " / " + json.max_points; + maxGrade.classList.remove("no-grade"); + } else { + firstTryError = "JSON returned without max points"; + } + } catch (err) { + firstTryError = err; + } + } else if (!firstTryError) { + firstTryError + "Unknown error fetching API response"; } - let json = await response.json(); - if (json && json.section.length > 0) { - // success case - // note; even if maxGrade is removed from the DOM, this will still work - maxGrade.textContent = " / " + json.section[0].period[0].assignment.filter(x => x.assignment_id == Number.parseInt(assignment.dataset.id.substr(2)))[0].max_points; - maxGrade.classList.remove("no-grade"); + if (!firstTryError) return; + + Logger.log(`Error directly fetching max points for (nonentered) assignment ${domAssignId}, reverting to list-search`); + + try { + response = await fetchApi(`users/${getUserId()}/grades?section_id=${courseId}`); + if (!response.ok) { + throw { status: response.status, error: response.statusText }; + } + let json = await response.json(); + + if (json && json.section.length > 0) { + // success case + // note; even if maxGrade is removed from the DOM, this will still work + maxGrade.textContent = " / " + json.section[0].period[0].assignment.filter(x => x.assignment_id == Number.parseInt(domAssignId))[0].max_points; + maxGrade.classList.remove("no-grade"); + } else { + throw "List search failed to obtain meaningful response"; + } + } catch (err) { + throw { listSearchErr: err, firstTryError: firstTryError }; } }; fetchQueue.push(f); diff --git a/js/home.js b/js/home.js index 312a8138..64027da0 100644 --- a/js/home.js +++ b/js/home.js @@ -2,7 +2,6 @@ let homeFeedContainer = document.getElementById("home-feed-container"); let feed = homeFeedContainer.querySelector(".feed .item-list .s-edge-feed"); -let rightCol = document.getElementById("right-column-inner"); /** * Creates a post from a broadcast @@ -76,73 +75,6 @@ function formatDateAsString(date) { return `${date.toLocaleString("en-US", { weekday: "short" })} ${date.toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric" })} at ${date.toLocaleString("en-US", { hour: "numeric", minute: "2-digit" }).toLowerCase()}`; } -async function createQuickAccess() { - let linkWrap; - - let wrapper = createElement("div", ["quick-access-wrapper"], {}, [ - createElement("h3", ["h3-med"], {}, [ - createElement("img", ["splus-logo-inline"], { src: chrome.runtime.getURL("imgs/plus-icon.png"), title: "Provided by Schoology Plus" }), - createElement("span", [], { textContent: "Quick Access" }), - createElement("a", ["quick-right-link", "splus-track-clicks"], { id: "quick-access-splus-settings", textContent: "Settings", href: "#splus-settings#setting-input-quickAccessVisibility" }) - ]), - createElement("div", ["date-header", "first"], {}, [ - createElement("h4", [], { textContent: "Pages" }) - ]), - (linkWrap = createElement("div", ["quick-link-wrapper"])) - ]); - - const PAGES = [ - { textContent: "Grade Report", href: "/grades/grades", id: "quick-access-grades" }, - { textContent: "Courses", href: "/courses", id: "quick-access-courses" }, - { textContent: "Mastery", href: "/mastery", id: "quick-access-mastery" }, - { textContent: "Groups", href: "/groups", id: "quick-access-groups" }, - { textContent: "Messages", href: "/messages", id: "quick-access-messages" }, - ]; - - for (let page of PAGES) { - let a = linkWrap.appendChild(createElement("a", ["quick-link", "splus-track-clicks"], page)); - a.dataset.splusTrackingLabel = "Quick Access"; - } - - wrapper.appendChild( - createElement("div", ["date-header"], {}, [ - createElement("h4", [], {}, [ - createElement("span", [], { textContent: "Courses" }), - createElement("a", ["quick-right-link", "splus-track-clicks"], { id: "quick-access-reorder", textContent: "Reorder", href: "/courses?reorder" }) - ]) - ]) - ); - - let sectionsList = (await fetchApiJson(`users/${getUserId()}/sections`)).section; - - if (!sectionsList || sectionsList.length == 0) { - wrapper.appendChild(createElement("p", ["quick-access-no-courses"], { textContent: "No courses found" })); - } else { - let courseOptionsButton; - let iconImage; - for (let section of sectionsList) { - wrapper.appendChild(createElement("div", ["quick-access-course"], {}, [ - (iconImage = createElement("div", ["splus-course-icon"], { dataset: { courseTitle: `${section.course_title}: ${section.section_title}` } })), - createElement("a", ["splus-track-clicks", "quick-course-link"], { textContent: `${section.course_title}: ${section.section_title}`, href: `/course/${section.id}`, dataset: { splusTrackingTarget: "quick-access-course-link", splusTrackingLabel: "Quick Access" } }), - createElement("div", ["icons-container"], {}, [ - createElement("a", ["icon", "icon-grades", "splus-track-clicks"], { href: `/course/${section.id}/student_grades`, title: "Grades", dataset: { splusTrackingTarget: "quick-access-grades-link", splusTrackingLabel: "Quick Access" } }), - createElement("a", ["icon", "icon-mastery", "splus-track-clicks"], { href: `/course/${section.id}/student_mastery`, title: "Mastery", dataset: { splusTrackingTarget: "quick-access-mastery-link", splusTrackingLabel: "Quick Access" } }), - (courseOptionsButton = createElement("a", ["icon", "icon-settings", "splus-track-clicks"], { href: "#", dataset: { splusTrackingTarget: "quick-access-settings-link", splusTrackingLabel: "Quick Access" } })) - ]) - ])); - - iconImage.style.backgroundImage = `url(${chrome.runtime.getURL("imgs/fallback-course-icon.svg")})`; - - courseOptionsButton.addEventListener("click", () => openModal("course-settings-modal", { - courseId: section.id, - courseName: `${section.course_title}: ${section.section_title}` - })); - } - } - - rightCol.prepend(wrapper); -} - if (Setting.getValue("broadcasts") !== "disabled") { (function () { let observer = new MutationObserver(function (mutations) { diff --git a/js/materials.js b/js/materials.js index 1cfbb703..1b665e17 100644 --- a/js/materials.js +++ b/js/materials.js @@ -271,10 +271,10 @@ // load grade information for this class, call grade hooks // this object contains ALL grades from this Schoology account, "keyed" by annoying IDs - // TODO Schoology API docs say this is paged, we should possible account for that? - let myGrades = await fetchApiJson(`/users/${userId}/grades`); + // they're filtered to this section though + let myGrades = await fetchApiJson(`/users/${userId}/grades?section_id=${classId}`); - let thisClassGrades = myGrades.section.find(x => x.section_id == classId); + let thisClassGrades = myGrades.section[0]; // start building our return object, which will follow a nicer format loadedGradeContainer = {}; @@ -284,23 +284,27 @@ loadedGradeContainer.dropboxes = {}; loadedGradeContainer.gradeDrops = {}; - // gradebook categories - for (let gradeCategory of thisClassGrades.grading_category) { - loadedGradeContainer.categories[gradeCategory.id] = gradeCategory; - Object.freeze(gradeCategory); - } + if (thisClassGrades) { - Object.freeze(loadedGradeContainer.categories); + // gradebook categories + for (let gradeCategory of thisClassGrades.grading_category) { + loadedGradeContainer.categories[gradeCategory.id] = gradeCategory; + Object.freeze(gradeCategory); + } - // assignment grades - // period is an array of object - // period[x].assignment is an array of grade objects (the ones we want to enumerate) - for (let assignment of thisClassGrades.period.reduce((accum, curr) => accum.concat(curr.assignment), [])) { - loadedGradeContainer.grades[assignment.assignment_id] = assignment; - Object.freeze(assignment); - } + Object.freeze(loadedGradeContainer.categories); - Object.freeze(loadedGradeContainer.grades); + // assignment grades + // period is an array of object + // period[x].assignment is an array of grade objects (the ones we want to enumerate) + for (let assignment of thisClassGrades.period.reduce((accum, curr) => accum.concat(curr.assignment), [])) { + loadedGradeContainer.grades[assignment.assignment_id] = assignment; + Object.freeze(assignment); + } + + Object.freeze(loadedGradeContainer.grades); + + } let missingAssignmentCt = 0; let missingAssignmentErrorCt = 0; diff --git a/js/preload.js b/js/preload.js index 45a4d9eb..43522893 100644 --- a/js/preload.js +++ b/js/preload.js @@ -37,11 +37,12 @@ var Logger = { // Process options Logger.log(`Loaded Schoology Plus version ${chrome.runtime.getManifest().version}${getBrowser() != "Chrome" || chrome.runtime.getManifest().update_url ? '' : ' (development version)'}`); var firstLoad = true; +document.documentElement.setAttribute("page", location.pathname); updateSettings(); var beta_tests = { - // "darktheme": "https://schoologypl.us", - // "newgrades": "https://schoologypl.us" + "darktheme": "https://schoologypl.us/docs/beta/darktheme", + "newgrades": "https://schoologypl.us" }; var defaultCourseIconUrlRegex = /\/sites\/[a-zA-Z0-9_-]+\/themes\/[%a-zA-Z0-9_-]+\/images\/course-default.(?:svg|png|jpe?g|gif)(\?[a-zA-Z0-9_%-]+(=[a-zA-Z0-9_%-]+)?(&[a-zA-Z0-9_%-]+(=[a-zA-Z0-9_%-]+)?)*)?$/; @@ -615,15 +616,23 @@ function updateSettings(callback) { new Setting( "quickAccessVisibility", "Quick Access", - "Enables or disables the quick access panel on the home page", + "[Reload Required to Reposition] Changes the visibility of the Quick Access panel on the homepage", "enabled", "select", { options: [ { - text: "Enabled", + text: "Top of Right Sidebar", value: "enabled" }, + { + text: "Between Overdue and Upcoming", + value: "belowOverdue" + }, + { + text: "Bottom of Right Sidebar", + value: "bottom" + }, { text: "Disabled", value: "disabled" @@ -1008,6 +1017,37 @@ function setCSSVariable(name, val) { document.documentElement.style.setProperty(`--${name}`, val); } +function createSvgLogo(...classes) { + let circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + circle.setAttribute("cx", 250); + circle.setAttribute("cy", 250); + circle.setAttribute("r", 230); + circle.setAttribute("style", "fill: none; stroke-width: 35px; stroke: currentColor;"); + let line1 = document.createElementNS("http://www.w3.org/2000/svg", "line"); + line1.setAttribute("x1", 250); + line1.setAttribute("y1", 125); + line1.setAttribute("x2", 250); + line1.setAttribute("y2", 375); + line1.setAttribute("style", "stroke-linecap: round; stroke-width: 35px; stroke: currentColor;"); + let line2 = document.createElementNS("http://www.w3.org/2000/svg", "line"); + line2.setAttribute("x1", 125); + line2.setAttribute("y1", 250); + line2.setAttribute("x2", 375); + line2.setAttribute("y2", 250); + line2.setAttribute("style", "stroke-linecap: round; stroke-width: 35px; stroke: currentColor;"); + + let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svg.setAttribute("viewBox", "0 0 500 500"); + + svg.append(circle, line1, line2); + + if (classes) { + svg.classList.add(...classes); + } + + return svg; +} + new Setting( "defaultDomain", "Default Schoology Domain", diff --git a/js/theme.js b/js/theme.js index 7ac04864..bc21fdfe 100644 --- a/js/theme.js +++ b/js/theme.js @@ -202,12 +202,12 @@ class Theme { return themes.find(x => x.name == name) || Theme.byName("Schoology Plus"); } - static setBackgroundColor(primaryColor, primaryLight, primaryDark, primaryVeryDark) { - if (primaryColor && primaryLight && primaryDark && primaryVeryDark) { + static setBackgroundColor(primaryColor, backgroundColor, hoverColor, borderColor) { + if (primaryColor && backgroundColor && hoverColor && borderColor) { document.documentElement.style.setProperty("--primary-color", primaryColor); - document.documentElement.style.setProperty("--background-color", primaryLight); - document.documentElement.style.setProperty("--hover-color", primaryDark); - document.documentElement.style.setProperty("--border-color", primaryVeryDark); + document.documentElement.style.setProperty("--background-color", backgroundColor); + document.documentElement.style.setProperty("--hover-color", hoverColor); + document.documentElement.style.setProperty("--border-color", borderColor); } } diff --git a/js/version-specific.js b/js/version-specific.js index d866b989..8d6d57a3 100644 --- a/js/version-specific.js +++ b/js/version-specific.js @@ -196,6 +196,16 @@ let migrationsTo = { } }, 10); } + }, + "6.4": function (currentVersion, previousVersion) { + saveBroadcasts([ + createBroadcast( + 640, + "Schoology Plus Dark Theme Beta", + "Schoology Plus is beta testing a new dark theme option! Join our Discord if you want to participate! Click here to join!", + new Date(2020, 7 /* August */, 16) + ) + ]); } }; diff --git a/lib/css/contextmenu.css b/lib/css/contextmenu.css index 0cfdc951..5b2a2932 100644 --- a/lib/css/contextmenu.css +++ b/lib/css/contextmenu.css @@ -1,16 +1,16 @@ @charset "UTF-8";/*! * jQuery contextMenu - Plugin for simple contextMenu handling * - * Version: v2.9.0 + * Version: v2.9.2 * * Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF) * Web: http://swisnl.github.io/jQuery-contextMenu/ * - * Copyright (c) 2011-2019 SWIS BV and contributors + * Copyright (c) 2011-2020 SWIS BV and contributors * * Licensed under * MIT License http://www.opensource.org/licenses/mit-license * - * Date: 2019-10-13T13:09:56.297Z - */@-webkit-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@-o-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@font-face{font-family:context-menu-icons;font-style:normal;font-weight:400;src:url(font/context-menu-icons.eot?4f0ru);src:url(font/context-menu-icons.eot?4f0ru#iefix) format("embedded-opentype"),url(font/context-menu-icons.woff2?4f0ru) format("woff2"),url(font/context-menu-icons.woff?4f0ru) format("woff"),url(font/context-menu-icons.ttf?4f0ru) format("truetype")}.context-menu-icon-add:before{content:"\EA01"}.context-menu-icon-copy:before{content:"\EA02"}.context-menu-icon-cut:before{content:"\EA03"}.context-menu-icon-delete:before{content:"\EA04"}.context-menu-icon-edit:before{content:"\EA05"}.context-menu-icon-loading:before{content:"\EA06"}.context-menu-icon-paste:before{content:"\EA07"}.context-menu-icon-quit:before{content:"\EA08"}.context-menu-icon::before{position:absolute;top:50%;left:0;width:2em;font-family:context-menu-icons;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon-loading:before{-webkit-animation:cm-spin 2s infinite;-o-animation:cm-spin 2s infinite;animation:cm-spin 2s infinite}.context-menu-icon.context-menu-icon--fa{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa::before{position:absolute;top:50%;left:0;width:2em;font-family:FontAwesome;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-icon--fa.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon--fa5{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa5 i,.context-menu-icon.context-menu-icon--fa5 svg{position:absolute;top:.3em;left:.5em;color:#2980b9}.context-menu-icon.context-menu-icon--fa5.context-menu-hover>i,.context-menu-icon.context-menu-icon--fa5.context-menu-hover>svg{color:#fff}.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i,.context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg{color:#bbb}.context-menu-list{position:absolute;display:inline-block;min-width:13em;max-width:26em;padding:.25em 0;margin:.3em;font-family:inherit;font-size:inherit;list-style-type:none;background:#fff;border:1px solid #bebebe;border-radius:.2em;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.5);box-shadow:0 2px 5px rgba(0,0,0,.5)}.context-menu-item{position:relative;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;padding:.2em 2em;color:#2f2f2f;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff}.context-menu-separator{padding:0;margin:.35em 0;border-bottom:1px solid #e6e6e6}.context-menu-item>label>input,.context-menu-item>label>textarea{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.context-menu-item.context-menu-hover{color:#fff;cursor:pointer;background-color:#2980b9}.context-menu-item.context-menu-disabled{color:#bbb;cursor:default;background-color:#fff}.context-menu-input.context-menu-hover{color:#2f2f2f;cursor:default}.context-menu-submenu:after{position:absolute;top:50%;right:.5em;z-index:1;width:0;height:0;content:'';border-color:transparent transparent transparent #2f2f2f;border-style:solid;border-width:.25em 0 .25em .25em;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%)}.context-menu-item.context-menu-input{padding:.3em .6em}.context-menu-input>label>*{vertical-align:top}.context-menu-input>label>input[type=checkbox],.context-menu-input>label>input[type=radio]{position:relative;top:.12em;margin-right:.4em}.context-menu-input>label{margin:0}.context-menu-input>label,.context-menu-input>label>input[type=text],.context-menu-input>label>select,.context-menu-input>label>textarea{display:block;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.context-menu-input>label>textarea{height:7em}.context-menu-item>.context-menu-list{top:.3em;right:-.3em;display:none}.context-menu-item.context-menu-visible>.context-menu-list{display:block}.context-menu-accesskey{text-decoration:underline} -/*# sourceMappingURL=jquery.contextMenu.min.css.map */ + * Date: 2020-05-13T13:55:37.023Z + */@-webkit-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@-o-keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@keyframes cm-spin{0%{-webkit-transform:translateY(-50%) rotate(0);-o-transform:translateY(-50%) rotate(0);transform:translateY(-50%) rotate(0)}100%{-webkit-transform:translateY(-50%) rotate(359deg);-o-transform:translateY(-50%) rotate(359deg);transform:translateY(-50%) rotate(359deg)}}@font-face{font-family:context-menu-icons;font-style:normal;font-weight:400;src:url(font/context-menu-icons.eot?33lxn);src:url(font/context-menu-icons.eot?33lxn#iefix) format("embedded-opentype"),url(font/context-menu-icons.woff2?33lxn) format("woff2"),url(font/context-menu-icons.woff?33lxn) format("woff"),url(font/context-menu-icons.ttf?33lxn) format("truetype")}.context-menu-icon-add:before{content:"\EA01"}.context-menu-icon-copy:before{content:"\EA02"}.context-menu-icon-cut:before{content:"\EA03"}.context-menu-icon-delete:before{content:"\EA04"}.context-menu-icon-edit:before{content:"\EA05"}.context-menu-icon-loading:before{content:"\EA06"}.context-menu-icon-paste:before{content:"\EA07"}.context-menu-icon-quit:before{content:"\EA08"}.context-menu-icon::before{position:absolute;top:50%;left:0;width:2em;font-family:context-menu-icons;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon-loading:before{-webkit-animation:cm-spin 2s infinite;-o-animation:cm-spin 2s infinite;animation:cm-spin 2s infinite}.context-menu-icon.context-menu-icon--fa{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa::before{position:absolute;top:50%;left:0;width:2em;font-family:FontAwesome;font-size:1em;font-style:normal;font-weight:400;line-height:1;color:#2980b9;text-align:center;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.context-menu-icon.context-menu-icon--fa.context-menu-hover:before{color:#fff}.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before{color:#bbb}.context-menu-icon.context-menu-icon--fa5{display:list-item;font-family:inherit;line-height:inherit}.context-menu-icon.context-menu-icon--fa5 i,.context-menu-icon.context-menu-icon--fa5 svg{position:absolute;top:.3em;left:.5em;color:#2980b9}.context-menu-icon.context-menu-icon--fa5.context-menu-hover>i,.context-menu-icon.context-menu-icon--fa5.context-menu-hover>svg{color:#fff}.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i,.context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg{color:#bbb}.context-menu-list{position:absolute;display:inline-block;min-width:13em;max-width:26em;padding:.25em 0;margin:.3em;font-family:inherit;font-size:inherit;list-style-type:none;background:#fff;border:1px solid #bebebe;border-radius:.2em;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.5);box-shadow:0 2px 5px rgba(0,0,0,.5)}.context-menu-item{position:relative;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;padding:.2em 2em;color:#2f2f2f;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff}.context-menu-separator{padding:0;margin:.35em 0;border-bottom:1px solid #e6e6e6}.context-menu-item>label>input,.context-menu-item>label>textarea{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.context-menu-item.context-menu-hover{color:#fff;cursor:pointer;background-color:#2980b9}.context-menu-item.context-menu-disabled{color:#bbb;cursor:default;background-color:#fff}.context-menu-input.context-menu-hover{color:#2f2f2f;cursor:default}.context-menu-submenu:after{position:absolute;top:50%;right:.5em;z-index:1;width:0;height:0;content:'';border-color:transparent transparent transparent #2f2f2f;border-style:solid;border-width:.25em 0 .25em .25em;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-o-transform:translateY(-50%);transform:translateY(-50%)}.context-menu-item.context-menu-input{padding:.3em .6em}.context-menu-input>label>*{vertical-align:top}.context-menu-input>label>input[type=checkbox],.context-menu-input>label>input[type=radio]{position:relative;top:.12em;margin-right:.4em}.context-menu-input>label{margin:0}.context-menu-input>label,.context-menu-input>label>input[type=text],.context-menu-input>label>select,.context-menu-input>label>textarea{display:block;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.context-menu-input>label>textarea{height:7em}.context-menu-item>.context-menu-list{top:.3em;right:-.3em;display:none}.context-menu-item.context-menu-visible>.context-menu-list{display:block}.context-menu-accesskey{text-decoration:underline} +/*# sourceMappingURL=jquery.contextMenu.min.css.map */ \ No newline at end of file diff --git a/lib/js/contextmenu.js b/lib/js/contextmenu.js index f88a79c2..94f4a13b 100644 --- a/lib/js/contextmenu.js +++ b/lib/js/contextmenu.js @@ -1,2 +1,2 @@ -!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(jQuery)}(function(m){"use strict";var a;m.support.htmlMenuitem="HTMLMenuItemElement"in window,m.support.htmlCommand="HTMLCommandElement"in window,m.support.eventSelectstart="onselectstart"in document.documentElement,m.ui&&m.widget||(m.cleanData=(a=m.cleanData,function(e){var t,n,o;for(o=0;null!=e[o];o++){n=e[o];try{(t=m._data(n,"events"))&&t.remove&&m(n).triggerHandler("remove")}catch(e){}}a(e)}));var c=null,d=!1,p=m(window),f=0,h={},x={},v={},g={selector:null,appendTo:null,trigger:"right",autoHide:!1,delay:200,reposition:!0,hideOnSecondTrigger:!1,selectableSubMenu:!1,classNames:{hover:"context-menu-hover",disabled:"context-menu-disabled",visible:"context-menu-visible",notSelectable:"context-menu-not-selectable",icon:"context-menu-icon",iconEdit:"context-menu-icon-edit",iconCut:"context-menu-icon-cut",iconCopy:"context-menu-icon-copy",iconPaste:"context-menu-icon-paste",iconDelete:"context-menu-icon-delete",iconAdd:"context-menu-icon-add",iconQuit:"context-menu-icon-quit",iconLoadingClass:"context-menu-icon-loading"},determinePosition:function(e){if(m.ui&&m.ui.position)e.css("display","block").position({my:"center top",at:"center bottom",of:this,offset:"0 5",collision:"fit"}).css("display","none");else{var t=this.offset();t.top+=this.outerHeight(),t.left+=this.outerWidth()/2-e.outerWidth()/2,e.css(t)}},position:function(e,t,n){var o;if(t||n){if("maintain"===t&&"maintain"===n)o=e.$menu.position();else{var a=e.$menu.offsetParent().offset();o={top:n-a.top,left:t-a.left}}var s=p.scrollTop()+p.height(),i=p.scrollLeft()+p.width(),c=e.$menu.outerHeight(),l=e.$menu.outerWidth();o.top+c>s&&(o.top-=c),o.top<0&&(o.top=0),o.left+l>i&&(o.left-=l),o.left<0&&(o.left=0),e.$menu.css(o)}else e.determinePosition.call(this,e.$menu)},positionSubmenu:function(e){if(void 0!==e)if(m.ui&&m.ui.position)e.css("display","block").position({my:"left top-5",at:"right top",of:this,collision:"flipfit fit"}).css("display","");else{var t={top:-9,left:this.outerWidth()-5};e.css(t)}},zIndex:1,animation:{duration:50,show:"slideDown",hide:"slideUp"},events:{preShow:m.noop,show:m.noop,hide:m.noop,activated:m.noop},callback:null,items:{}},s={timer:null,pageX:null,pageY:null},b={abortevent:function(e){e.preventDefault(),e.stopImmediatePropagation()},contextmenu:function(e){var t=m(this);if(!1!==e.data.events.preShow(t,e)&&("right"===e.data.trigger&&(e.preventDefault(),e.stopImmediatePropagation()),!("right"!==e.data.trigger&&"demand"!==e.data.trigger&&e.originalEvent||!(void 0===e.mouseButton||!e.data||"left"===e.data.trigger&&0===e.mouseButton||"right"===e.data.trigger&&2===e.mouseButton)||t.hasClass("context-menu-active")||t.hasClass("context-menu-disabled")))){if(c=t,e.data.build){var n=e.data.build(c,e);if(!1===n)return;if(e.data=m.extend(!0,{},g,e.data,n||{}),!e.data.items||m.isEmptyObject(e.data.items))throw window.console&&(console.error||console.log).call(console,"No items specified to show in contextMenu"),new Error("No Items specified");e.data.$trigger=c,$.create(e.data)}$.show.call(t,e.data,e.pageX,e.pageY)}},click:function(e){e.preventDefault(),e.stopImmediatePropagation(),m(this).trigger(m.Event("contextmenu",{data:e.data,pageX:e.pageX,pageY:e.pageY}))},mousedown:function(e){var t=m(this);c&&c.length&&!c.is(t)&&c.data("contextMenu").$menu.trigger("contextmenu:hide"),2===e.button&&(c=t.data("contextMenuActive",!0))},mouseup:function(e){var t=m(this);t.data("contextMenuActive")&&c&&c.length&&c.is(t)&&!t.hasClass("context-menu-disabled")&&(e.preventDefault(),e.stopImmediatePropagation(),(c=t).trigger(m.Event("contextmenu",{data:e.data,pageX:e.pageX,pageY:e.pageY}))),t.removeData("contextMenuActive")},mouseenter:function(e){var t=m(this),n=m(e.relatedTarget),o=m(document);n.is(".context-menu-list")||n.closest(".context-menu-list").length||c&&c.length||(s.pageX=e.pageX,s.pageY=e.pageY,s.data=e.data,o.on("mousemove.contextMenuShow",b.mousemove),s.timer=setTimeout(function(){s.timer=null,o.off("mousemove.contextMenuShow"),(c=t).trigger(m.Event("contextmenu",{data:s.data,pageX:s.pageX,pageY:s.pageY}))},e.data.delay))},mousemove:function(e){s.pageX=e.pageX,s.pageY=e.pageY},mouseleave:function(e){var t=m(e.relatedTarget);if(!t.is(".context-menu-list")&&!t.closest(".context-menu-list").length){try{clearTimeout(s.timer)}catch(e){}s.timer=null}},layerClick:function(a){var s,i,c=m(this).data("contextMenuRoot"),l=a.button,r=a.pageX,u=a.pageY,d=void 0===r;a.preventDefault(),setTimeout(function(){if(d)null!=c&&null!==c.$menu&&void 0!==c.$menu&&c.$menu.trigger("contextmenu:hide");else{var e,t="left"===c.trigger&&0===l||"right"===c.trigger&&2===l;if(document.elementFromPoint&&c.$layer){if(c.$layer.hide(),(s=document.elementFromPoint(r-p.scrollLeft(),u-p.scrollTop())).isContentEditable){var n=document.createRange(),o=window.getSelection();n.selectNode(s),n.collapse(!0),o.removeAllRanges(),o.addRange(n)}m(s).trigger(a),c.$layer.show()}if(c.hideOnSecondTrigger&&t&&null!==c.$menu&&void 0!==c.$menu)c.$menu.trigger("contextmenu:hide");else{if(c.reposition&&t)if(document.elementFromPoint){if(c.$trigger.is(s))return void c.position.call(c.$trigger,c,r,u)}else if(i=c.$trigger.offset(),e=m(window),i.top+=e.scrollTop(),i.top<=a.pageY&&(i.left+=e.scrollLeft(),i.left<=a.pageX&&(i.bottom=i.top+c.$trigger.outerHeight(),i.bottom>=a.pageY&&(i.right=i.left+c.$trigger.outerWidth(),i.right>=a.pageX))))return void c.position.call(c.$trigger,c,r,u);s&&t&&c.$trigger.one("contextmenu:hidden",function(){m(s).contextMenu({x:r,y:u,button:l})}),null!=c&&null!==c.$menu&&void 0!==c.$menu&&c.$menu.trigger("contextmenu:hide")}}},50)},keyStop:function(e,t){t.isInput||e.preventDefault(),e.stopPropagation()},key:function(e){var t={};c&&(t=c.data("contextMenu")||{}),void 0===t.zIndex&&(t.zIndex=0);var n=0,o=function(e){""!==e.style.zIndex?n=e.style.zIndex:null!==e.offsetParent&&void 0!==e.offsetParent?o(e.offsetParent):null!==e.parentElement&&void 0!==e.parentElement&&o(e.parentElement)};if(o(e.target),!(t.$menu&&parseInt(n,10)>parseInt(t.$menu.css("zIndex"),10))){switch(e.keyCode){case 9:case 38:if(b.keyStop(e,t),t.isInput){if(9===e.keyCode&&e.shiftKey)return e.preventDefault(),t.$selected&&t.$selected.find("input, textarea, select").blur(),void(null!==t.$menu&&void 0!==t.$menu&&t.$menu.trigger("prevcommand"));if(38===e.keyCode&&"checkbox"===t.$selected.find("input, textarea, select").prop("type"))return void e.preventDefault()}else if(9!==e.keyCode||e.shiftKey)return void(null!==t.$menu&&void 0!==t.$menu&&t.$menu.trigger("prevcommand"));break;case 40:if(b.keyStop(e,t),!t.isInput)return void(null!==t.$menu&&void 0!==t.$menu&&t.$menu.trigger("nextcommand"));if(9===e.keyCode)return e.preventDefault(),t.$selected&&t.$selected.find("input, textarea, select").blur(),void(null!==t.$menu&&void 0!==t.$menu&&t.$menu.trigger("nextcommand"));if(40===e.keyCode&&"checkbox"===t.$selected.find("input, textarea, select").prop("type"))return void e.preventDefault();break;case 37:if(b.keyStop(e,t),t.isInput||!t.$selected||!t.$selected.length)break;if(t.$selected.parent().hasClass("context-menu-root"))break;var a=t.$selected.parent().parent();return t.$selected.trigger("contextmenu:blur"),void(t.$selected=a);case 39:if(b.keyStop(e,t),t.isInput||!t.$selected||!t.$selected.length)break;var s=t.$selected.data("contextMenu")||{};if(s.$menu&&t.$selected.hasClass("context-menu-submenu"))return t.$selected=null,s.$selected=null,void s.$menu.trigger("nextcommand");break;case 35:case 36:return t.$selected&&t.$selected.find("input, textarea, select").length?void 0:((t.$selected&&t.$selected.parent()||t.$menu).children(":not(."+t.classNames.disabled+", ."+t.classNames.notSelectable+")")[36===e.keyCode?"first":"last"]().trigger("contextmenu:focus"),void e.preventDefault());case 13:if(b.keyStop(e,t),t.isInput){if(t.$selected&&!t.$selected.is("textarea, select"))return void e.preventDefault();break}return void(void 0!==t.$selected&&null!==t.$selected&&t.$selected.trigger("mouseup"));case 32:case 33:case 34:return void b.keyStop(e,t);case 27:return b.keyStop(e,t),void(null!==t.$menu&&void 0!==t.$menu&&t.$menu.trigger("contextmenu:hide"));default:var i=String.fromCharCode(e.keyCode).toUpperCase();if(t.accesskeys&&t.accesskeys[i])return void t.accesskeys[i].$node.trigger(t.accesskeys[i].$menu?"contextmenu:focus":"mouseup")}e.stopPropagation(),void 0!==t.$selected&&null!==t.$selected&&t.$selected.trigger(e)}},prevItem:function(e){e.stopPropagation();var t=m(this).data("contextMenu")||{},n=m(this).data("contextMenuRoot")||{};if(t.$selected){var o=t.$selected;(t=t.$selected.parent().data("contextMenu")||{}).$selected=o}for(var a=t.$menu.children(),s=t.$selected&&t.$selected.prev().length?t.$selected.prev():a.last(),i=s;s.hasClass(n.classNames.disabled)||s.hasClass(n.classNames.notSelectable)||s.is(":hidden");)if((s=s.prev().length?s.prev():a.last()).is(i))return;t.$selected&&b.itemMouseleave.call(t.$selected.get(0),e),b.itemMouseenter.call(s.get(0),e);var c=s.find("input, textarea, select");c.length&&c.focus()},nextItem:function(e){e.stopPropagation();var t=m(this).data("contextMenu")||{},n=m(this).data("contextMenuRoot")||{};if(t.$selected){var o=t.$selected;(t=t.$selected.parent().data("contextMenu")||{}).$selected=o}for(var a=t.$menu.children(),s=t.$selected&&t.$selected.next().length?t.$selected.next():a.first(),i=s;s.hasClass(n.classNames.disabled)||s.hasClass(n.classNames.notSelectable)||s.is(":hidden");)if((s=s.next().length?s.next():a.first()).is(i))return;t.$selected&&b.itemMouseleave.call(t.$selected.get(0),e),b.itemMouseenter.call(s.get(0),e);var c=s.find("input, textarea, select");c.length&&c.focus()},focusInput:function(){var e=m(this).closest(".context-menu-item"),t=e.data(),n=t.contextMenu,o=t.contextMenuRoot;o.$selected=n.$selected=e,o.isInput=n.isInput=!0},blurInput:function(){var e=m(this).closest(".context-menu-item").data(),t=e.contextMenu;e.contextMenuRoot.isInput=t.isInput=!1},menuMouseenter:function(){m(this).data().contextMenuRoot.hovering=!0},menuMouseleave:function(e){var t=m(this).data().contextMenuRoot;t.$layer&&t.$layer.is(e.relatedTarget)&&(t.hovering=!1)},itemMouseenter:function(e){var t=m(this),n=t.data(),o=n.contextMenu,a=n.contextMenuRoot;a.hovering=!0,e&&a.$layer&&a.$layer.is(e.relatedTarget)&&(e.preventDefault(),e.stopImmediatePropagation()),(o.$menu?o:a).$menu.children("."+a.classNames.hover).trigger("contextmenu:blur").children(".hover").trigger("contextmenu:blur"),t.hasClass(a.classNames.disabled)||t.hasClass(a.classNames.notSelectable)?o.$selected=null:t.trigger("contextmenu:focus")},itemMouseleave:function(e){var t=m(this),n=t.data(),o=n.contextMenu,a=n.contextMenuRoot;if(a!==o&&a.$layer&&a.$layer.is(e.relatedTarget))return void 0!==a.$selected&&null!==a.$selected&&a.$selected.trigger("contextmenu:blur"),e.preventDefault(),e.stopImmediatePropagation(),void(a.$selected=o.$selected=o.$node);o&&o.$menu&&o.$menu.hasClass("context-menu-visible")||t.trigger("contextmenu:blur")},itemClick:function(e){var t,n=m(this),o=n.data(),a=o.contextMenu,s=o.contextMenuRoot,i=o.contextMenuKey;if(!(!a.items[i]||n.is("."+s.classNames.disabled+", .context-menu-separator, ."+s.classNames.notSelectable)||n.is(".context-menu-submenu")&&!1===s.selectableSubMenu)){if(e.preventDefault(),e.stopImmediatePropagation(),m.isFunction(a.callbacks[i])&&Object.prototype.hasOwnProperty.call(a.callbacks,i))t=a.callbacks[i];else{if(!m.isFunction(s.callback))return;t=s.callback}!1!==t.call(s.$trigger,i,s,e)?s.$menu.trigger("contextmenu:hide"):s.$menu.parent().length&&$.update.call(s.$trigger,s)}},inputClick:function(e){e.stopImmediatePropagation()},hideMenu:function(e,t){var n=m(this).data("contextMenuRoot");$.hide.call(n.$trigger,n,t&&t.force)},focusItem:function(e){e.stopPropagation();var t=m(this),n=t.data(),o=n.contextMenu,a=n.contextMenuRoot;t.hasClass(a.classNames.disabled)||t.hasClass(a.classNames.notSelectable)||(t.addClass([a.classNames.hover,a.classNames.visible].join(" ")).parent().find(".context-menu-item").not(t).removeClass(a.classNames.visible).filter("."+a.classNames.hover).trigger("contextmenu:blur"),o.$selected=a.$selected=t,o&&o.$node&&o.$node.hasClass("context-menu-submenu")&&o.$node.addClass(a.classNames.hover),o.$node&&a.positionSubmenu.call(o.$node,o.$menu))},blurItem:function(e){e.stopPropagation();var t=m(this),n=t.data(),o=n.contextMenu,a=n.contextMenuRoot;o.autoHide&&t.removeClass(a.classNames.visible),t.removeClass(a.classNames.hover),o.$selected=null}},$={show:function(n,e,t){var o=m(this),a={};if(m("#context-menu-layer").trigger("mousedown"),n.$trigger=o,!1!==n.events.show.call(o,n))if(!1!==$.update.call(o,n)){if(n.position.call(o,n,e,t),n.zIndex){var s=n.zIndex;"function"==typeof n.zIndex&&(s=n.zIndex.call(o,n)),a.zIndex=function(e){for(var t=0,n=e;t=Math.max(t,parseInt(n.css("z-index"),10)||0),(n=n.parent())&&n.length&&!(-1<"html body".indexOf(n.prop("nodeName").toLowerCase())););return t}(o)+s}$.layer.call(n.$menu,n,a.zIndex),n.$menu.find("ul").css("zIndex",a.zIndex+1),n.$menu.css(a)[n.animation.show](n.animation.duration,function(){o.trigger("contextmenu:visible"),$.activated(n),n.events.activated(n)}),o.data("contextMenu",n).addClass("context-menu-active"),m(document).off("keydown.contextMenu").on("keydown.contextMenu",b.key),n.autoHide&&m(document).on("mousemove.contextMenuAutoHide",function(e){var t=o.offset();t.right=t.left+o.outerWidth(),t.bottom=t.top+o.outerHeight(),!n.$layer||n.hovering||e.pageX>=t.left&&e.pageX<=t.right&&e.pageY>=t.top&&e.pageY<=t.bottom||setTimeout(function(){n.hovering||null===n.$menu||void 0===n.$menu||n.$menu.trigger("contextmenu:hide")},50)})}else c=null;else c=null},hide:function(t,e){var n=m(this);if(t=t||(n.data("contextMenu")||{}),e||!t.events||!1!==t.events.hide.call(n,t)){if(n.removeData("contextMenu").removeClass("context-menu-active"),t.$layer){setTimeout((o=t.$layer,function(){o.remove()}),10);try{delete t.$layer}catch(e){t.$layer=null}}var o;c=null,t.$menu.find("."+t.classNames.hover).trigger("contextmenu:blur"),t.$selected=null,t.$menu.find("."+t.classNames.visible).removeClass(t.classNames.visible),m(document).off(".contextMenuAutoHide").off("keydown.contextMenu"),t.$menu&&t.$menu[t.animation.hide](t.animation.duration,function(){t.build&&(t.$menu.remove(),m.each(t,function(e){switch(e){case"ns":case"selector":case"build":case"trigger":return!0;default:t[e]=void 0;try{delete t[e]}catch(e){}return!0}})),setTimeout(function(){n.trigger("contextmenu:hidden")},10)})}},create:function(r,u){function d(e){var t=m("");if(e._accesskey)e._beforeAccesskey&&t.append(document.createTextNode(e._beforeAccesskey)),m("").addClass("context-menu-accesskey").text(e._accesskey).appendTo(t),e._afterAccesskey&&t.append(document.createTextNode(e._afterAccesskey));else if(e.isHtmlName){if(void 0!==e.accesskey)throw new Error("accesskeys are not compatible with HTML names and cannot be used together in the same item");t.html(e.name)}else t.text(e.name);return t}void 0===u&&(u=r),r.$menu=m('
').addClass(r.className||"").data({contextMenu:r,contextMenuRoot:u}),r.dataAttr&&m.each(r.dataAttr,function(e,t){r.$menu.attr("data-"+r.key,t)}),m.each(["callbacks","commands","inputs"],function(e,t){r[t]={},u[t]||(u[t]={})}),u.accesskeys||(u.accesskeys={}),m.each(r.items,function(n,o){var e=m('').addClass(o.className||""),t=null,a=null;if(e.on("click",m.noop),"string"!=typeof o&&"cm_separator"!==o.type||(o={type:"cm_seperator"}),o.$node=e.data({contextMenu:r,contextMenuRoot:u,contextMenuKey:n}),void 0!==o.accesskey)for(var s,i=function(e){for(var t,n=e.split(/\s+/),o=[],a=0;t=n[a];a++)t=t.charAt(0).toUpperCase(),o.push(t);return o}(o.accesskey),c=0;s=i[c];c++)if(!u.accesskeys[s]){var l=(u.accesskeys[s]=o).name.match(new RegExp("^(.*?)("+s+")(.*)$","i"));l&&(o._beforeAccesskey=l[1],o._accesskey=l[2],o._afterAccesskey=l[3]);break}if(o.type&&v[o.type])v[o.type].call(e,o,r,u),m.each([r,u],function(e,t){t.commands[n]=o,!m.isFunction(o.callback)||void 0!==t.callbacks[n]&&void 0!==r.type||(t.callbacks[n]=o.callback)});else{switch("cm_seperator"===o.type?e.addClass("context-menu-separator "+u.classNames.notSelectable):"html"===o.type?e.addClass("context-menu-html "+u.classNames.notSelectable):"sub"!==o.type&&o.type?(t=m("").appendTo(e),d(o).appendTo(t),e.addClass("context-menu-input"),r.hasTypes=!0,m.each([r,u],function(e,t){t.commands[n]=o,t.inputs[n]=o})):o.items&&(o.type="sub"),o.type){case"cm_seperator":break;case"text":a=m('').attr("name","context-menu-input-"+n).val(o.value||"").appendTo(t);break;case"textarea":a=m('').attr("name","context-menu-input-"+n).val(o.value||"").appendTo(t),o.height&&a.height(o.height);break;case"checkbox":a=m('').attr("name","context-menu-input-"+n).val(o.value||"").prop("checked",!!o.selected).prependTo(t);break;case"radio":a=m('').attr("name","context-menu-input-"+o.radio).val(o.value||"").prop("checked",!!o.selected).prependTo(t);break;case"select":a=m('').attr("name","context-menu-input-"+n).appendTo(t),o.options&&(m.each(o.options,function(e,t){m("").val(e).text(t).appendTo(a)}),a.val(o.selected));break;case"sub":d(o).appendTo(e),o.appendTo=o.$node,e.data("contextMenu",o).addClass("context-menu-submenu"),o.callback=null,"function"==typeof o.items.then?$.processPromises(o,u,o.items):$.create(o,u);break;case"html":m(o.html).appendTo(e);break;default:m.each([r,u],function(e,t){t.commands[n]=o,!m.isFunction(o.callback)||void 0!==t.callbacks[n]&&void 0!==r.type||(t.callbacks[n]=o.callback)}),d(o).appendTo(e)}o.type&&"sub"!==o.type&&"html"!==o.type&&"cm_seperator"!==o.type&&(a.on("focus",b.focusInput).on("blur",b.blurInput),o.events&&a.on(o.events,r)),o.icon&&(m.isFunction(o.icon)?o._icon=o.icon.call(this,this,e,n,o):"string"!=typeof o.icon||"fab "!==o.icon.substring(0,4)&&"fas "!==o.icon.substring(0,4)&&"fad "!==o.icon.substring(0,4)&&"far "!==o.icon.substring(0,4)&&"fal "!==o.icon.substring(0,4)?"string"==typeof o.icon&&"fa-"===o.icon.substring(0,3)?o._icon=u.classNames.icon+" "+u.classNames.icon+"--fa fa "+o.icon:o._icon=u.classNames.icon+" "+u.classNames.icon+"-"+o.icon:(e.addClass(u.classNames.icon+" "+u.classNames.icon+"--fa5"),o._icon=m('')),"string"==typeof o._icon?e.addClass(o._icon):e.prepend(o._icon))}o.$input=a,o.$label=t,e.appendTo(r.$menu),!r.hasTypes&&m.support.eventSelectstart&&e.on("selectstart.disableTextSelect",b.abortevent)}),r.$node||r.$menu.css("display","none").addClass("context-menu-root"),r.$menu.appendTo(r.appendTo||document.body)},resize:function(e,t){var n;e.css({position:"absolute",display:"block"}),e.data("width",(n=e.get(0)).getBoundingClientRect?Math.ceil(n.getBoundingClientRect().width):e.outerWidth()+1),e.css({position:"static",minWidth:"0px",maxWidth:"100000px"}),e.find("> li > ul").each(function(){$.resize(m(this),!0)}),t||e.find("ul").addBack().css({position:"",display:"",minWidth:"",maxWidth:""}).outerWidth(function(){return m(this).data("width")})},update:function(i,c){var l=this;void 0===c&&(c=i,$.resize(i.$menu));var r=!1;return i.$menu.children().each(function(){var e,t=m(this),n=t.data("contextMenuKey"),o=i.items[n],a=m.isFunction(o.disabled)&&o.disabled.call(l,n,c)||!0===o.disabled;if((e=m.isFunction(o.visible)?o.visible.call(l,n,c):void 0===o.visible||!0===o.visible)&&(r=!0),t[e?"show":"hide"](),t[a?"addClass":"removeClass"](c.classNames.disabled),m.isFunction(o.icon)){t.removeClass(o._icon);var s=o.icon.call(this,l,t,n,o);"string"==typeof s?t.addClass(s):t.prepend(s)}if(o.type)switch(t.find("input, select, textarea").prop("disabled",a),o.type){case"text":case"textarea":o.$input.val(o.value||"");break;case"checkbox":case"radio":o.$input.val(o.value||"").prop("checked",!!o.selected);break;case"select":o.$input.val((0===o.selected?"0":o.selected)||"")}o.$menu&&$.update.call(l,o,c)&&(r=!0)}),r},layer:function(e,t){var n=e.$layer=m('').css({height:p.height(),width:p.width(),display:"block",position:"fixed","z-index":t,top:0,left:0,opacity:0,filter:"alpha(opacity=0)","background-color":"#000"}).data("contextMenuRoot",e).insertBefore(this).on("contextmenu",b.abortevent).on("mousedown",b.layerClick);return void 0===document.body.style.maxWidth&&n.css({position:"absolute",height:m(document).height()}),n},processPromises:function(e,t,n){function o(e,t,n){void 0===n?(n={error:{name:"No items and no error item",icon:"context-menu-icon context-menu-icon-quit"}},window.console&&(console.error||console.log).call(console,'When you reject a promise, provide an "items" object, equal to normal sub-menu items')):"string"==typeof n&&(n={error:{name:n}}),a(e,t,n)}function a(e,t,n){void 0!==t.$menu&&t.$menu.is(":visible")&&(e.$node.removeClass(t.classNames.iconLoadingClass),e.items=n,$.create(e,t,!0),$.update(e,t),t.positionSubmenu.call(e.$node,e.$menu))}e.$node.addClass(t.classNames.iconLoadingClass),n.then(function(e,t,n){void 0===n&&o(void 0),a(e,t,n)}.bind(this,e,t),o.bind(this,e,t))},activated:function(e){var t=e.$menu,n=t.offset(),o=m(window).height(),a=m(window).scrollTop(),s=t.height();o