-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcontent.js
More file actions
188 lines (175 loc) · 6.05 KB
/
content.js
File metadata and controls
188 lines (175 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
console.log("NetAcad Scraper content script loaded and ready.");
let debounceTimeout;
function debouncedScrape() {
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(() => {
chrome.storage.sync.get(["processOnSwitch"], (result) => {
if (result.processOnSwitch === false) {
console.debug(
"NetAcad Scraper: Page switch detected but 'Process on Page Switch' is disabled.",
);
return;
}
if (typeof window.scrapeData === "function") {
console.debug(
"NetAcad Scraper: Mutation detected, re-initiating scrape...",
);
window.scrapeData();
} else {
console.error(
"NetAcad Scraper: window.scrapeData not found for debounced call.",
);
}
});
}, 1200);
}
function initMutationObserver() {
console.debug("NetAcad Scraper: Attempting to initialize MutationObserver.");
const appRoot = document.querySelector("app-root");
if (appRoot && appRoot.shadowRoot) {
const pageView = appRoot.shadowRoot.querySelector("page-view");
if (pageView && pageView.shadowRoot) {
const targetNode = pageView.shadowRoot;
const observerConfig = { childList: true, subtree: true };
const observer = new MutationObserver((mutationsList, observer) => {
console.debug(
"NetAcad Scraper: MutationObserver detected DOM change in page-view's shadowRoot.",
);
debouncedScrape();
});
observer.observe(targetNode, observerConfig);
console.debug(
"NetAcad Scraper: MutationObserver initialized and observing page-view's shadowRoot.",
);
} else {
console.warn(
"NetAcad Scraper: MutationObserver setup failed - page-view or its shadowRoot not found. Observer will not be active.",
);
}
} else {
console.warn(
"NetAcad Scraper: MutationObserver setup failed - app-root or its shadowRoot not found. Observer will not be active.",
);
}
}
if (typeof window.scrapeData !== "function") {
if (typeof scrapeData === "function") {
window.scrapeData = scrapeData;
} else {
console.error(
"scrapeData function not found in global scope. scraper.js might not have loaded correctly or before this script.",
);
}
}
const autoRunScraper = async () => {
if (!document.querySelector("app-root")) {
const frameContext = window.top === window ? "main page" : "an iframe";
console.debug(
`NetAcad Scraper: autoRunScraper - app-root not found in this frame context (${frameContext}). Auto-run aborted.`,
);
return;
}
if (document.readyState !== "complete") {
await new Promise((resolve) =>
window.addEventListener("load", resolve, { once: true }),
);
}
await new Promise((resolve) => setTimeout(resolve, 500));
const storedData = await chrome.storage.sync.get([
"geminiApiKey",
"showAnswers",
]);
if (
storedData.geminiApiKey &&
(typeof storedData.showAnswers === "undefined" ||
storedData.showAnswers === true)
) {
console.debug(
"NetAcad Scraper: API key found and showAnswers enabled. Attempting initial scrape and setting up observer.",
);
if (typeof window.scrapeData === "function") {
await window.scrapeData(); // Perform initial scrape
initMutationObserver(); // Setup observer after initial scrape attempt
} else {
console.error(
"NetAcad Scraper: Critical - window.scrapeData not defined for auto-run and observer setup.",
);
}
} else if (storedData.geminiApiKey && storedData.showAnswers === false) {
console.debug(
"NetAcad Scraper: showAnswers is disabled. Skipping initial scrape and observer.",
);
} else {
console.debug(
"NetAcad Scraper: Page loaded. No API key. Observer not set. Use popup to set key and process.",
);
}
};
autoRunScraper();
// Listener for messages from the popup
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "processPage") {
console.debug(
"NetAcad Scraper (content.js): Received processPage message from popup.",
);
// Check if this frame contains the app-root element
if (document.querySelector("app-root")) {
if (
request.hasOwnProperty("showAnswers") &&
request.showAnswers === false
) {
console.debug(
"NetAcad Scraper (content.js): showAnswers is false, not scraping.",
);
sendResponse({
success: true,
result: false,
message: "AI answers are hidden by user setting.",
});
return false;
}
console.debug(
"NetAcad Scraper (content.js): app-root found in this frame. Calling window.scrapeData().",
);
if (typeof window.scrapeData === "function") {
window
.scrapeData()
.then((result) => {
console.debug(
`NetAcad Scraper (content.js): scrapeData completed in this frame with result: ${result}`,
);
sendResponse({ success: true, result: result });
})
.catch((error) => {
console.error(
"NetAcad Scraper (content.js): Error calling scrapeData from message listener:",
error,
);
sendResponse({ success: false, error: error.toString() });
});
return true; // Indicates that sendResponse will be called asynchronously
} else {
console.error(
"NetAcad Scraper (content.js): window.scrapeData not found in this frame for processPage message.",
);
sendResponse({
success: false,
error: "scrapeData_not_found_in_frame",
});
}
} else {
console.debug(
"NetAcad Scraper (content.js): app-root NOT found in this frame. Ignoring processPage message.",
);
return false;
}
}
return false;
});
// Periodic check to see if the content script is still active. Can be removed.
setInterval(() => {
console.debug(
"NetAcad Scraper content script is active - periodic check @ " +
new Date().toLocaleTimeString(),
);
}, 30000);