diff --git a/css/modern/all.css b/css/modern/all.css
index 7440fa2..4dfc81d 100644
--- a/css/modern/all.css
+++ b/css/modern/all.css
@@ -1931,6 +1931,10 @@ variable-intellisense {
color: var(--text) !important;
}
+[modern=true]:root .porcelain_pattern {
+ background: var(--accent) !important;
+}
+
[modern=true]:root .fc-state-highlight {
background: var(--active) !important;
}
@@ -2141,9 +2145,8 @@ variable-intellisense {
color: var(--text) !important;
}
-[modern=true][dark=true]:root .assessment-delivery-landing-app div._3dHTa::after {
- content: "WARNING: A dark theme is enabled and might prevent you from reading certain questions. If you can't read a question, you can temporarily disable dark theme using the Toggle Theme button on the navigation bar.";
- display: block;
+[modern=true][dark=true]:root #assessment-darktheme-warning-message[data-popup=true] {
+ display: block !important;
text-align: center;
width: 50%;
margin-left: 25%;
@@ -2154,6 +2157,15 @@ variable-intellisense {
border-radius: var(--border-radius);
}
+[modern=true][dark=true]:root #assessment-darktheme-warning-message .click-to-hide {
+ padding-top: 10px !important;
+}
+
+[modern=true][dark=true]:root #assessment-darktheme-warning-message .click-to-hide span {
+ text-decoration: underline;
+ cursor: pointer;
+}
+
[modern=true]:root .mathquill-formula {
filter: Invert(var(--theme-is-dark)) !important;
}
diff --git a/css/modern/theme-editor.css b/css/modern/theme-editor.css
index 2ac57c8..9ef81aa 100644
--- a/css/modern/theme-editor.css
+++ b/css/modern/theme-editor.css
@@ -200,3 +200,7 @@ variable-intellisense {
transition: .3s ease-out !important;
color: var(--modern-contrast-text) !important;
}
+
+[modern=true]:root #create-preset-dropdown > li:hover {
+ background-color: var(--modern-active);
+}
diff --git a/js/all-idle.js b/js/all-idle.js
index 84ee02d..43cb8e9 100644
--- a/js/all-idle.js
+++ b/js/all-idle.js
@@ -1,4 +1,4 @@
-(async function() {
+(async function () {
// Wait for loader.js to finish running
while (!window.splusLoaded) {
await new Promise(resolve => setTimeout(resolve, 10));
@@ -356,6 +356,39 @@
}).observe(document.getElementById("body"), { attributes: true, attributeFilter: ["aria-hidden"] });
})();
+(function () {
+ setTimeout(() => {
+ let assessmentStartContainer = document.querySelector(`.assessment-delivery-landing-app div._3dHTa`);
+
+ if (assessmentStartContainer) {
+ assessmentStartContainer.appendChild(
+ createElement(
+ "div",
+ [],
+ {
+ id: "assessment-darktheme-warning-message",
+ textContent: "WARNING: A dark theme is enabled and might prevent you from reading certain questions. If you can't read a question, you can temporarily disable dark theme using the Toggle Theme button on the navigation bar.",
+ dataset: { popup: Setting.getNestedValue("popup", "assessmentDarkThemeWarning", true) },
+ style: { display: "none" }
+ },
+ [
+ createElement("p", ["click-to-hide"], {}, [
+ createElement("span", [], { textContent: "Hide this once", onclick: () => document.getElementById("assessment-darktheme-warning-message").remove() }),
+ createElement("b", [], { textContent: " • " }),
+ createElement("span", [], {
+ textContent: "Never show again", onclick: () => {
+ Setting.setNestedValue("popup", "assessmentDarkThemeWarning", false);
+ document.getElementById("assessment-darktheme-warning-message").dataset.popup = "false";
+ }
+ }),
+ ])
+ ]
+ )
+ )
+ }
+ }, 1000);
+})();
+
function parseSettingsHash() {
let hashes = location.hash.split('#');
if (hashes.length > 1 && hashes[1] === "splus-settings") {
diff --git a/js/all.js b/js/all.js
index d6ae5ce..c0aa600 100644
--- a/js/all.js
+++ b/js/all.js
@@ -239,7 +239,7 @@ let modals = [
"contributors-modal",
"Schoology Plus Contributors",
createElement("div", ["splus-modal-contents"], undefined, [
- createElement("h2", ["setting-entry"], { textContent: "Contributors" }),
+ createElement("h2", ["setting-entry"], { textContent: "Lead Developers" }),
createElement("div", ["setting-entry"], {}, [
createElement("h3", ["setting-title"], {}, [
createElement("a", [], { href: "https://github.com/aopell", textContent: "Aaron Opell (@aopell)" })
@@ -252,65 +252,92 @@ let modals = [
]),
createElement("p", ["setting-description"], { textContent: "Lead developer" })
]),
+ createElement("h2", ["setting-entry"], { textContent: "Code Contributions" }),
createElement("div", ["setting-entry"], {}, [
- createElement("h3", ["setting-title"], {}, [
- createElement("a", [], { href: "https://github.com/xd-arsenic", textContent: "Alexander (@xd-arsenic)" }),
- createElement("span", [], { textContent: ", " }),
- createElement("a", [], { href: "https://github.com/Roguim", textContent: "@Roguim" }),
- createElement("span", [], { textContent: ", " }),
- createElement("a", [], { href: "https://github.com/reteps", textContent: "Peter Stenger (@reteps)" }),
- createElement("span", [], { textContent: ", " }),
- createElement("a", [], { href: "https://github.com/EricPedley", textContent: "Eric Pedley (@EricPedley)" }),
- createElement("span", [], { textContent: ", and " }),
- createElement("a", [], { href: "https://github.com/KTibow", textContent: "@KTibow" }),
- ]),
- createElement("p", ["setting-description"], { textContent: "Various code contributions" })
+ createElement("ul", ["contributor-list"], {
+ style: { listStyle: "inside" },
+ innerHTML: (function (contribs) {
+ let retVal = "";
+ for (let i = 0; i < contribs.length; i++) {
+ if (contribs[i].url) {
+ retVal += `
${contribs[i].name}`;
+ } else {
+ retVal += `${contribs[i].name}`
+ }
+ }
+ return retVal;
+ })([
+ { name: "Alexander (@xd-arsenic)", url: "https://github.com/xd-arsenic" },
+ { name: "@Roguim", url: "https://github.com/Roguim" },
+ { name: "Peter Stenger (@reteps)", url: "https://github.com/reteps" },
+ { name: "Eric Pedley (@EricPedley)", url: "https://github.com/EricPedley" },
+ { name: "@KTibow", url: "https://github.com/KTibow" },
+ ])
+ }),
]),
+ createElement("h2", ["setting-entry"], { textContent: "Testing, Bug Reporting, and/or Discord Moderation" }),
createElement("div", ["setting-entry"], {}, [
- createElement("h3", ["setting-title"], {}, [
- // contributors list
- createElement("span", [], {
- innerHTML: (function (contribs) {
- let retVal = "";
- for (let i = 0; i < contribs.length; i++) {
- retVal += `${contribs[i]}`;
- if (i == contribs.length - 2) {
- retVal += ", and ";
- } else if (i != contribs.length - 1) {
- retVal += ", ";
- }
+ createElement("ul", ["contributor-list"], {
+ style: { listStyle: "inside" },
+ innerHTML: (function (contribs) {
+ let retVal = "";
+ for (let i = 0; i < contribs.length; i++) {
+ if (contribs[i].url) {
+ retVal += `${contribs[i].name}`;
+ } else {
+ retVal += `${contribs[i].name}`
}
- return retVal;
- })(["DinosoftLabs", "Eucalyp", "Flat Icons", "Freepik", "Maxim Basinski", "Pixel Buddha", "Smashicons", "Twitter", "Vectors Market", "Vitaly Gorbachev", "srip", "surang", "Pixelmeetup", "photo3idea_studio"])
- }),
- createElement("span", [], { textContent: " from " }),
- createElement("a", [], { href: "https://www.flaticon.com/", textContent: "flaticon.com" })
- ]),
+ }
+ return retVal;
+ })([
+ { name: "atomicproton#4444" },
+ { name: "penguinee232#7792" },
+ { name: "Cody Lomeli" },
+ { name: "Airbus A330-200#0001" },
+ { name: "Ark#9999" },
+ { name: "ASAMU#1919" },
+ { name: "Baconnated Churro#4954" },
+ { name: "Blumiere#7442" },
+ { name: "Krishy Fishy#3333" },
+ { name: "meepypotato07#7816" },
+ { name: "phool#0200" },
+ { name: "RVxBot#7862" },
+ { name: "TechFun#9234" },
+ ])
+ }),
+ ]),
+ createElement("h2", ["setting-entry"], { textContent: "Icons and Images" }),
+ createElement("div", ["setting-entry"], {}, [
+
+ createElement("ul", ["contributor-list"], {
+ style: { listStyle: "inside" },
+ innerHTML: (function (contribs) {
+ let retVal = "";
+ for (let i = 0; i < contribs.length; i++) {
+ retVal += `${contribs[i]}`;
+ }
+ return retVal;
+ })(["DinosoftLabs", "Eucalyp", "Flat Icons", "Freepik", "Maxim Basinski", "Pixel Buddha", "Smashicons", "Twitter", "Vectors Market", "Vitaly Gorbachev", "srip", "surang", "Pixelmeetup", "photo3idea_studio"])
+ }),
+ ]),
+ createElement("div", ["setting-entry"], {}, [
createElement("p", ["setting-description"], {}, [
createElement("span", [], { textContent: "Many custom course icons (under " }),
- createElement("a", [], { href: "http://creativecommons.org/licenses/by/3.0/", title: "Creative Commons BY 3.0", target: "_blank", textContent: "CC BY 3.0" }),
- createElement("span", [], { textContent: ")" }),
+ createElement("a", [], { href: "https://creativecommons.org/licenses/by/3.0/", title: "Creative Commons BY 3.0", target: "_blank", textContent: "CC BY 3.0" }),
+ createElement("span", [], { textContent: ") from " }),
+ createElement("a", [], { href: "https://www.flaticon.com/", title: "flaticon", target: "_blank", textContent: "flaticon.com" }),
createElement("p", [], { textContent: "Bundled:" }),
createElement("div", ["splus-indent-1"], {
innerHTML:
- '- Exclamation mark (grades page modified indicator): By Pixel Buddha from flaticon.com under CC BY 3.0
'
+ '"
})
]),
-
- createElement("ul", ["setting-description"], {}, [
- createElement("li", [], { textContent: "" })
- ])
- ]),
- createElement("div", ["setting-entry"], {}, [
- createElement("h3", ["setting-title"], {}, [
- createElement("a", [], { href: "http://www.iconninja.com/edit-draw-pencile-write-icon-899685", textContent: "Pencil Icon from IconNinja" })
- ]),
- createElement("p", ["setting-description"], { textContent: "Bundled as edit grade icon" }, [])
]),
createElement("div", ["setting-entry"], {}, [
- createElement("h3", ["setting-title"], { textContent: "...and more" }),
+ createElement("h2", ["setting-title"], { textContent: "...and countless other people" }),
createElement("p", ["setting-description"], { textContent: "For various ideas and suggestions" })
]),
createElement("div", ["setting-entry"], {}, [
@@ -1193,6 +1220,9 @@ function indicateSubmittedAssignments() {
} else if (assignmentElement.href.includes("/event/")) {
// Calendar events
assignmentId = assignmentElement.href.match(/event\/(\d+)/)[1];
+ } else if (assignmentElement.href.includes("/external_tool/")) {
+ // External tools
+ assignmentId = assignmentElement.href.match(/external_tool\/(\d+)/)[1];
}
// add a CSS class for both states, so we can distinguish 'loading' from known-(in)complete
diff --git a/js/analytics.js b/js/analytics.js
index 22db937..647af03 100644
--- a/js/analytics.js
+++ b/js/analytics.js
@@ -32,13 +32,13 @@ var trackEvent = function (target, action, label = undefined, value = undefined)
}
}
- chrome.storage.sync.get({ analytics: getBrowser() === "Firefox" ? "disabled" : "enabled", theme: "" }, s => {
+ chrome.storage.sync.get({ analytics: getBrowser() === "Firefox" ? "disabled" : "enabled", theme: "", beta: "", newVersion: "" }, s => {
if (s.analytics === "enabled") {
- enableAnalytics(s.theme);
+ enableAnalytics(s.theme, s.beta, s.newVersion);
}
});
- function enableAnalytics(selectedTheme) {
+ function enableAnalytics(selectedTheme, beta, newVersion) {
// isogram
let r = 'ga';
window['GoogleAnalyticsObject'] = r;
@@ -54,6 +54,8 @@ var trackEvent = function (target, action, label = undefined, value = undefined)
ga('set', 'dimension2', location.host);
ga('set', 'dimension3', selectedTheme);
ga('set', 'dimension4', document.documentElement.getAttribute("modern"));
+ ga('set', 'dimension5', beta);
+ ga('set', 'dimension6', newVersion);
ga('send', 'pageview', location.pathname.replace(/\/\d{3,}\b/g, "/*") + location.search);
trackEvent = function (target, action, label = undefined, value = undefined) {
diff --git a/js/background-permissions.js b/js/background-permissions.js
index 5d466c8..1999219 100644
--- a/js/background-permissions.js
+++ b/js/background-permissions.js
@@ -192,7 +192,7 @@ function updateItem({ tabId }) {
};
if (!chrome.runtime.lastError && origin) {
// Manifest permissions can't be removed; this disables the toggle on those domains
- const isDefault = origin.endsWith("schoology.com");
+ const isDefault = origin.endsWith("schoology.com") || origin.endsWith("lms.lausd.net");
settings.enabled = !isDefault;
// We might have temporary permission as part of `activeTab`, so it needs to be properly checked
diff --git a/js/grades.js b/js/grades.js
index dfded48..b0d67ab 100644
--- a/js/grades.js
+++ b/js/grades.js
@@ -123,7 +123,7 @@ var fetchQueue = [];
// if there's no PERIOD \d string in the course name, match will return null; in that case, use the array [null, i++]
// OR is lazy, so the ++ won't trigger unnecessarily; upperPeriodSortBound is our array key, and we use it to give a unique index (after all course) to periodless courses
- coursesByPeriod[Number.parseInt((title.textContent.match(/[Pp][Ee][Rr][Ii]?[Oo]?[Dd]?\s*(\d+)/) || [null, upperPeriodSortBound++])[1])] = course;
+ coursesByPeriod[Number.parseInt((title.textContent.match(/\b[Pp][Ee]?[Rr]?[Ii]?[Oo]?[Dd]?\s*(\d+)/) || [null, upperPeriodSortBound++])[1])] = course;
// Fix width of assignment columns
table.appendChild(createElement("colgroup", [], {}, [
diff --git a/js/preload.js b/js/preload.js
index 132453e..78f489f 100644
--- a/js/preload.js
+++ b/js/preload.js
@@ -1,4 +1,4 @@
-(async function() {
+(async function () {
// Wait for loader.js to finish running
while (!window.splusLoaded) {
await new Promise(resolve => setTimeout(resolve, 10));
@@ -23,10 +23,10 @@ var defaultCourseIconUrlRegex = /\/sites\/[a-zA-Z0-9_-]+\/themes\/[%a-zA-Z0-9_-]
// Functions
/** @type {HTMLDivElement} */
-var modalContents;
+var modalContents = undefined;
function getModalContents() {
- return modalContents;
+ return modalContents || createElement("p", [], { textContent: "Error loading settings" });
}
function backgroundPageFetch(url, init, bodyReadType) {
diff --git a/js/theme-editor.js b/js/theme-editor.js
index 0a4ba88..452439a 100644
--- a/js/theme-editor.js
+++ b/js/theme-editor.js
@@ -945,6 +945,12 @@ function saveTheme(apply = false) {
let themes = s.themes.filter(x => x.name != (origThemeName || t.name));
themes.push(t);
chrome.storage.sync.set({ themes: themes }, () => {
+ if (chrome.runtime.lastError) {
+ if (chrome.runtime.lastError.message.includes("QUOTA_BYTES_PER_ITEM")) {
+ alert("No space remaining to save theme. Please delete another theme or make this theme smaller in order to save.");
+ throw new Error("No space remaining to save theme. Please delete another theme or make this theme smaller in order to save.");
+ }
+ }
ConfirmModal.open("Theme saved successfully", "", ["OK"], () => {
origThemeName = t.name;
if (apply) chrome.storage.sync.set({ theme: t.name }, () => location.href = `https://${defaultDomain}`);
@@ -1082,7 +1088,7 @@ function editTheme(name, replaceName = undefined) {
previewSection.classList.add("show-editor-controls");
output.removeAttribute("readonly");
Array.from(iconList.querySelectorAll(".class-name, .icon-url")).map(x => x.setAttribute("contenteditable", "true"));
- origThemeName = name;
+ origThemeName = replaceName || name;
document.querySelector("#json-output + label").textContent = "JSON (Paste to import a theme)";
}
diff --git a/manifest.json b/manifest.json
index c0b1ea7..8088894 100644
--- a/manifest.json
+++ b/manifest.json
@@ -9,7 +9,7 @@
"id": "schoology.plus@aopell.me"
}
},
- "version": "7.3",
+ "version": "7.3.1",
"icons": {
"128": "imgs/icon@128.png",
"64": "imgs/icon@64.png",
diff --git a/scss/modern/all.scss b/scss/modern/all.scss
index 4fb7fa7..d4592b4 100644
--- a/scss/modern/all.scss
+++ b/scss/modern/all.scss
@@ -926,6 +926,7 @@ variable-intellisense {
// Grades Page
.gradebook-course.hierarchical-grading-report {
+
.period-row .grade-column,
.category-row .grade-column,
.item-row .grade-column {
@@ -1255,10 +1256,6 @@ variable-intellisense {
}
}
- ._2kpZl:focus:not(:active), ._2T2dA, ._2W23R:active, ._3OAXJ:hover:not(:active) {
- background-color: var(--accent) !important;
- }
-
// Resources Page
@@ -2367,17 +2364,27 @@ variable-intellisense {
// Common Assesment (New Schoology Assessments)
- &[dark=true] .assessment-delivery-landing-app div._3dHTa::after {
- content: "WARNING: A dark theme is enabled and might prevent you from reading certain questions. If you can't read a question, you can temporarily disable dark theme using the Toggle Theme button on the navigation bar.";
- display: block;
- text-align: center;
- width: 50%;
- margin-left: 25%;
- font-size: 16px;
- padding: var(--padding);
- background-color: var(--highlight);
- border: var(--border-size) solid rgba(0, 0, 0, 0.5);
- border-radius: var(--border-radius);
+ &[dark=true] #assessment-darktheme-warning-message {
+ &[data-popup=true] {
+ display: block !important;
+ text-align: center;
+ width: 50%;
+ margin-left: 25%;
+ font-size: 16px;
+ padding: var(--padding);
+ background-color: var(--highlight);
+ border: var(--border-size) solid rgba(0, 0, 0, 0.5);
+ border-radius: var(--border-radius);
+ }
+
+ .click-to-hide {
+ padding-top: 10px !important;
+
+ span {
+ text-decoration: underline;
+ cursor: pointer;
+ }
+ }
}
// LaTeX Math Formulas
diff --git a/scss/modern/theme-editor.scss b/scss/modern/theme-editor.scss
index b574a6f..b086e08 100644
--- a/scss/modern/theme-editor.scss
+++ b/scss/modern/theme-editor.scss
@@ -214,4 +214,8 @@ variable-intellisense {
color: var(--modern-contrast-text) !important;
}
}
+
+ #create-preset-dropdown>li:hover {
+ background-color: var(--modern-active);
+ }
}
\ No newline at end of file