diff --git a/package.json b/package.json index fd357c1..703f6f6 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,8 @@ "storage", "scripting", "webNavigation", - "tabs" + "tabs", + "nativeMessaging" ], "host_permissions": [ "https://utdallas.collegescheduler.com/terms/*/courses/*", diff --git a/src/background.ts b/src/background.ts index 49b537c..ed7028f 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1,6 +1,6 @@ import { Storage } from '@plasmohq/storage'; -import { CourseHeader, scrapeCourseData } from '~content'; +import { CourseHeader, listenForTableChange, scrapeCourseData } from '~content'; export interface ShowCourseTabPayload { header: CourseHeader; @@ -21,6 +21,7 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { details.url, ) ) { + //Scrape data chrome.scripting.executeScript( { target: { @@ -38,6 +39,15 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }, ); + //Listen for table change to rescrape data + chrome.tabs.sendMessage(details.tabId, 'disconnectObserver'); + chrome.scripting.executeScript({ + target: { + tabId: details.tabId, + }, + func: listenForTableChange, + }); + //Store tab info chrome.action.setBadgeText({ text: '!' }); chrome.action.setBadgeBackgroundColor({ color: 'green' }); courseTabId = details.tabId; @@ -48,6 +58,27 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }); +/** Rescrape data on table change */ +chrome.runtime.onMessage.addListener(function (message) { + if (message === 'tableChange') { + chrome.scripting.executeScript( + { + target: { + tabId: courseTabId, + }, + func: scrapeCourseData, + }, + async function (resolve) { + if (resolve && resolve[0] && resolve[0].result) { + const result: ShowCourseTabPayload = resolve[0].result; + scrapedCourseData = result; + await storage.set('scrapedCourseData', scrapedCourseData); + } + }, + ); + } +}); + /** Sets the icon to be active if we're on a course tab */ chrome.tabs.onActivated.addListener(async () => { const cachedTabUrl: string = await storage.get('courseTabUrl'); diff --git a/src/content.ts b/src/content.ts index 25e0e78..77fb366 100644 --- a/src/content.ts +++ b/src/content.ts @@ -85,9 +85,41 @@ export async function scrapeCourseData() { }); const courseRowCells = courseRow.querySelector('tr'); courseRowCells.insertBefore(newTd, courseRowCells.children[7]); + //Increase Disabled Reasons row colspan if necessary + const sectionDisabled = courseRow.querySelector('tr:nth-child(3) > td'); + if (sectionDisabled !== null) { + sectionDisabled.colSpan = sectionDisabled.colSpan + 1; + } // collapse section details sectionDetailsButton.click(); }); return [...new Set(professors)]; } } + +/** This listens for clicks on the buttons that switch between the enabled and disabled professor tabs and reports back to background.ts */ +export function listenForTableChange() { + const observer = new MutationObserver((mutationsList) => { + for (const mutation of mutationsList) { + if ( + mutation.type === 'attributes' && + mutation.attributeName === 'class' + ) { + //button corresponding to shown table is given an active class + if (mutation.target.classList.contains('active')) { + chrome.runtime.sendMessage('tableChange'); + } + } + } + }); + observer.observe(document.body, { + attributes: true, + subtree: true, + }); + //remove observer when ordered by backgroud.ts to avoid duplicates + chrome.runtime.onMessage.addListener(function (message) { + if (message === 'disconnectObserver') { + observer.disconnect(); + } + }); +}