From 8a91e3cfc1eb588756bc053763f3b1a751076381 Mon Sep 17 00:00:00 2001 From: Tyler Hill Date: Thu, 4 Jan 2024 02:09:59 -0600 Subject: [PATCH 1/3] Initial --- package.json | 3 ++- src/background.ts | 33 ++++++++++++++++++++++++++++++++- src/content.ts | 25 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) 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..51e89c9 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; @@ -16,6 +16,7 @@ const storage = new Storage(); /** Injects the content script if we hit a course page */ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { + console.log('hello'); if ( /^.*:\/\/utdallas\.collegescheduler\.com\/terms\/.*\/courses\/.+$/.test( details.url, @@ -38,6 +39,13 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }, ); + chrome.tabs.sendMessage(details.tabId, 'disconnect'); + chrome.scripting.executeScript({ + target: { + tabId: details.tabId, + }, + func: listenForTableChange, + }); chrome.action.setBadgeText({ text: '!' }); chrome.action.setBadgeBackgroundColor({ color: 'green' }); courseTabId = details.tabId; @@ -48,6 +56,29 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }); +chrome.runtime.onMessage.addListener(function (message) { + if (message === 'tableChange') { + console.log('hi'); + chrome.scripting.executeScript( + { + target: { + tabId: courseTabId, + }, + // content script injection only works reliably on the prod packaged extension + // b/c of the plasmo dev server connections + 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..2fb3b45 100644 --- a/src/content.ts +++ b/src/content.ts @@ -91,3 +91,28 @@ export async function scrapeCourseData() { return [...new Set(professors)]; } } + +export async function listenForTableChange() { + const observer = new MutationObserver((mutationsList) => { + for (const mutation of mutationsList) { + if ( + mutation.type === 'attributes' && + mutation.attributeName === 'class' + ) { + if (mutation.target.classList.contains('active')) { + console.log(mutation.target.innerText.split(' ')[0]); + chrome.runtime.sendMessage('tableChange'); + } + } + } + }); + observer.observe(document.body, { + attributes: true, + subtree: true, + }); + chrome.runtime.onMessage.addListener(function (message) { + if (message === 'disconnect') { + observer.disconnect(); + } + }); +} From 2e306aae9452bae193689e164dd7fa86679e6049 Mon Sep 17 00:00:00 2001 From: Tyler Hill Date: Thu, 4 Jan 2024 14:48:19 -0600 Subject: [PATCH 2/3] Layout fix and cleanup --- src/background.ts | 4 ---- src/content.ts | 8 ++++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/background.ts b/src/background.ts index 51e89c9..93a8e05 100644 --- a/src/background.ts +++ b/src/background.ts @@ -16,7 +16,6 @@ const storage = new Storage(); /** Injects the content script if we hit a course page */ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { - console.log('hello'); if ( /^.*:\/\/utdallas\.collegescheduler\.com\/terms\/.*\/courses\/.+$/.test( details.url, @@ -58,14 +57,11 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { chrome.runtime.onMessage.addListener(function (message) { if (message === 'tableChange') { - console.log('hi'); chrome.scripting.executeScript( { target: { tabId: courseTabId, }, - // content script injection only works reliably on the prod packaged extension - // b/c of the plasmo dev server connections func: scrapeCourseData, }, async function (resolve) { diff --git a/src/content.ts b/src/content.ts index 2fb3b45..4d9beb1 100644 --- a/src/content.ts +++ b/src/content.ts @@ -85,6 +85,11 @@ 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(); }); @@ -92,7 +97,7 @@ export async function scrapeCourseData() { } } -export async function listenForTableChange() { +export function listenForTableChange() { const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if ( @@ -100,7 +105,6 @@ export async function listenForTableChange() { mutation.attributeName === 'class' ) { if (mutation.target.classList.contains('active')) { - console.log(mutation.target.innerText.split(' ')[0]); chrome.runtime.sendMessage('tableChange'); } } From 05b9af9ff27b7c4a0a10b93d9b162210be0fe20e Mon Sep 17 00:00:00 2001 From: Tyler Hill Date: Thu, 4 Jan 2024 14:56:59 -0600 Subject: [PATCH 3/3] Add comments --- src/background.ts | 6 +++++- src/content.ts | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/background.ts b/src/background.ts index 93a8e05..ed7028f 100644 --- a/src/background.ts +++ b/src/background.ts @@ -21,6 +21,7 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { details.url, ) ) { + //Scrape data chrome.scripting.executeScript( { target: { @@ -38,13 +39,15 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }, ); - chrome.tabs.sendMessage(details.tabId, 'disconnect'); + //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; @@ -55,6 +58,7 @@ chrome.webNavigation.onHistoryStateUpdated.addListener((details) => { } }); +/** Rescrape data on table change */ chrome.runtime.onMessage.addListener(function (message) { if (message === 'tableChange') { chrome.scripting.executeScript( diff --git a/src/content.ts b/src/content.ts index 4d9beb1..77fb366 100644 --- a/src/content.ts +++ b/src/content.ts @@ -97,6 +97,7 @@ export async function scrapeCourseData() { } } +/** 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) { @@ -104,6 +105,7 @@ export function listenForTableChange() { 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'); } @@ -114,8 +116,9 @@ export function listenForTableChange() { attributes: true, subtree: true, }); + //remove observer when ordered by backgroud.ts to avoid duplicates chrome.runtime.onMessage.addListener(function (message) { - if (message === 'disconnect') { + if (message === 'disconnectObserver') { observer.disconnect(); } });