M12: Browser Extension - Chrome/Edge Manifest V3 extension - Popup UI for saving pages - Context menu integration (save page/selection/link) - Background service worker - Content script for extraction M13: Shell Completions - Bash, Zsh, Fish, PowerShell completions - Dynamic node ID completion - Dynamic tag completion - Dynamic graph completion - Auto-install command (--install)
81 lines
2.1 KiB
JavaScript
81 lines
2.1 KiB
JavaScript
// Content script for Cortex browser extension
|
|
// Injected into web pages to extract content
|
|
|
|
// Extract page content
|
|
function extractContent() {
|
|
const title = document.title;
|
|
|
|
// Get selected text
|
|
const selection = window.getSelection()?.toString() || '';
|
|
|
|
// Try to find main content using common selectors
|
|
let content = '';
|
|
const contentSelectors = [
|
|
'article',
|
|
'[role="main"]',
|
|
'main',
|
|
'.post-content',
|
|
'.article-content',
|
|
'.entry-content',
|
|
'.content',
|
|
'#content',
|
|
];
|
|
|
|
for (const selector of contentSelectors) {
|
|
const el = document.querySelector(selector);
|
|
if (el && el.textContent) {
|
|
content = el.textContent;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Fall back to body content
|
|
if (!content) {
|
|
content = document.body.textContent || '';
|
|
}
|
|
|
|
// Clean up content
|
|
content = content
|
|
.replace(/\s+/g, ' ')
|
|
.replace(/\n{3,}/g, '\n\n')
|
|
.trim()
|
|
.slice(0, 100000); // Limit to 100k chars
|
|
|
|
// Get meta description
|
|
const metaDesc = document.querySelector('meta[name="description"]')?.content || '';
|
|
|
|
// Get author
|
|
const author = document.querySelector('meta[name="author"]')?.content ||
|
|
document.querySelector('[rel="author"]')?.textContent || '';
|
|
|
|
// Get published date
|
|
const datePublished = document.querySelector('meta[property="article:published_time"]')?.content ||
|
|
document.querySelector('time[datetime]')?.getAttribute('datetime') || '';
|
|
|
|
return {
|
|
title,
|
|
content,
|
|
selection,
|
|
excerpt: metaDesc || content.slice(0, 200),
|
|
url: window.location.href,
|
|
author,
|
|
datePublished,
|
|
};
|
|
}
|
|
|
|
// Listen for messages from popup or background
|
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
if (request.action === 'extract') {
|
|
try {
|
|
const data = extractContent();
|
|
sendResponse(data);
|
|
} catch (err) {
|
|
sendResponse({ error: err.message });
|
|
}
|
|
}
|
|
return true; // Keep channel open for async response
|
|
});
|
|
|
|
// Make extract function available globally for background script injection
|
|
window.__cortexExtract = extractContent;
|