|
| 1 | +import { extractPageDataInline } from "@/lib/extract-page-data-inline"; |
| 2 | + |
1 | 3 | console.log("[AI SEO Copilot] Service worker initializing..."); |
2 | 4 |
|
3 | 5 | // Disable automatic panel opening - we'll handle it manually for per-tab scoping |
@@ -47,19 +49,6 @@ async function persistPanelTabs(): Promise<void> { |
47 | 49 | async function addPanelTab(tabId: number): Promise<void> { |
48 | 50 | panelTabs.add(tabId); |
49 | 51 | await persistPanelTabs(); |
50 | | - |
51 | | - // Immediately disable the panel on ALL other tabs |
52 | | - // This ensures the panel only shows on the tab where it was opened |
53 | | - try { |
54 | | - const allTabs = await chrome.tabs.query({}); |
55 | | - for (const tab of allTabs) { |
56 | | - if (tab.id && tab.id !== tabId) { |
57 | | - chrome.sidePanel.setOptions({ tabId: tab.id, enabled: false }); |
58 | | - } |
59 | | - } |
60 | | - } catch { |
61 | | - // Ignore errors |
62 | | - } |
63 | 52 | } |
64 | 53 |
|
65 | 54 | async function removePanelTab(tabId: number): Promise<void> { |
@@ -165,59 +154,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { |
165 | 154 | console.log("[AI SEO Copilot] Executing analyzer script..."); |
166 | 155 | const results = await chrome.scripting.executeScript({ |
167 | 156 | target: { tabId }, |
168 | | - func: () => { |
169 | | - const getMetaContent = (name: string): string => { |
170 | | - const el = |
171 | | - document.querySelector<HTMLMetaElement>(`meta[name="${name}"]`) || |
172 | | - document.querySelector<HTMLMetaElement>(`meta[property="${name}"]`); |
173 | | - return el?.content ?? ""; |
174 | | - }; |
175 | | - const getHeadings = (tag: string): string[] => |
176 | | - Array.from(document.querySelectorAll(tag)).map( |
177 | | - (el) => el.textContent?.trim() ?? "", |
178 | | - ); |
179 | | - const images = Array.from(document.querySelectorAll<HTMLImageElement>("img")).map((img) => ({ |
180 | | - src: img.src, alt: img.alt ?? "", width: img.naturalWidth || null, height: img.naturalHeight || null, |
181 | | - })); |
182 | | - const links = Array.from(document.querySelectorAll<HTMLAnchorElement>("a[href]")); |
183 | | - const host = window.location.hostname; |
184 | | - let internal = 0, external = 0; |
185 | | - for (const link of links) { |
186 | | - try { new URL(link.href).hostname === host ? internal++ : external++; } |
187 | | - catch { internal++; } |
188 | | - } |
189 | | - const bodyText = document.body?.innerText ?? ""; |
190 | | - const ogTags: Record<string, string> = {}; |
191 | | - document.querySelectorAll<HTMLMetaElement>('meta[property^="og:"]').forEach((el) => { |
192 | | - ogTags[el.getAttribute("property")!] = el.content; |
193 | | - }); |
194 | | - const twitterTags: Record<string, string> = {}; |
195 | | - document.querySelectorAll<HTMLMetaElement>('meta[name^="twitter:"]').forEach((el) => { |
196 | | - twitterTags[el.getAttribute("name")!] = el.content; |
197 | | - }); |
198 | | - const paragraphs = Array.from(document.querySelectorAll("p")) |
199 | | - .map((el) => el.textContent?.trim() ?? "").filter(Boolean); |
200 | | - const jsRes = Array.from(document.querySelectorAll<HTMLScriptElement>("script[src]")) |
201 | | - .map((el) => el.src).filter(Boolean); |
202 | | - const cssRes = Array.from(document.querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]')) |
203 | | - .map((el) => el.href).filter(Boolean); |
204 | | - const schemas = Array.from(document.querySelectorAll<HTMLScriptElement>('script[type="application/ld+json"]')); |
205 | | - const schemaTypes: string[] = []; |
206 | | - for (const s of schemas) { try { const d = JSON.parse(s.textContent ?? ""); if (d["@type"]) schemaTypes.push(d["@type"]); } catch {} } |
207 | | - return { |
208 | | - url: window.location.href, title: document.title ?? "", |
209 | | - metaDescription: getMetaContent("description"), metaKeywords: getMetaContent("keywords"), |
210 | | - canonical: document.querySelector<HTMLLinkElement>('link[rel="canonical"]')?.href ?? "", |
211 | | - h1: getHeadings("h1"), h2: getHeadings("h2"), h3: getHeadings("h3"), |
212 | | - h4: getHeadings("h4"), h5: getHeadings("h5"), h6: getHeadings("h6"), |
213 | | - images, ogTags, twitterTags, wordCount: bodyText.split(/\s+/).filter(Boolean).length, |
214 | | - internalLinks: internal, externalLinks: external, |
215 | | - lang: document.documentElement.lang ?? "", paragraphs, |
216 | | - resources: { js: jsRes, css: cssRes }, |
217 | | - schemaMarkup: { types: schemaTypes, count: schemas.length }, |
218 | | - ogImage: getMetaContent("og:image"), imageFileSizes: [], |
219 | | - }; |
220 | | - }, |
| 157 | + func: extractPageDataInline, |
221 | 158 | }); |
222 | 159 | console.log("[AI SEO Copilot] executeScript completed, results:", results?.length ?? 0); |
223 | 160 | const data = results?.[0]?.result; |
|
0 commit comments