This commit is contained in:
2025-03-07 17:45:17 +08:00
commit 936af0c4ec
114 changed files with 37662 additions and 0 deletions

243
extension/content.js Normal file
View File

@@ -0,0 +1,243 @@
// Function to extract comments from the page
function extractComments() {
const comments = [];
let platform = detectPlatform();
// Different extraction strategies based on the platform
if (platform === 'facebook') {
extractFacebookComments(comments);
} else if (platform === 'youtube') {
extractYoutubeComments(comments);
} else if (platform === 'twitter') {
extractTwitterComments(comments);
} else if (platform === 'instagram') {
extractInstagramComments(comments);
} else if (platform === 'linkedin') {
extractLinkedinComments(comments);
} else {
// Generic extraction for other platforms
extractGenericComments(comments);
}
return comments;
}
// Detect the current platform
function detectPlatform() {
const url = window.location.hostname;
if (url.includes('facebook.com')) return 'facebook';
if (url.includes('youtube.com')) return 'youtube';
if (url.includes('twitter.com') || url.includes('x.com')) return 'twitter';
if (url.includes('instagram.com')) return 'instagram';
if (url.includes('linkedin.com')) return 'linkedin';
return 'other';
}
// Platform-specific extraction functions
function extractFacebookComments(comments) {
// Facebook comment selectors
const commentElements = document.querySelectorAll('[aria-label="Comment"]');
commentElements.forEach((element, index) => {
try {
const authorElement = element.querySelector('a');
const contentElement = element.querySelector('[data-ad-comet-preview="message"]');
const timestampElement = element.querySelector('a[href*="comment_id"]');
const likesElement = element.querySelector('[aria-label*="reactions"]');
if (contentElement) {
comments.push({
id: `fb-comment-${index}`,
author: authorElement ? authorElement.textContent : 'Facebook User',
content: contentElement.textContent,
timestamp: timestampElement ? timestampElement.textContent : 'Recently',
likes: likesElement ? parseInt(likesElement.textContent) || 0 : 0,
platform: 'facebook'
});
}
} catch (error) {
console.error('Error extracting Facebook comment:', error);
}
});
}
function extractYoutubeComments(comments) {
// YouTube comment selectors
const commentElements = document.querySelectorAll('ytd-comment-thread-renderer');
commentElements.forEach((element, index) => {
try {
const authorElement = element.querySelector('#author-text');
const contentElement = element.querySelector('#content-text');
const timestampElement = element.querySelector('.published-time-text');
const likesElement = element.querySelector('#vote-count-middle');
if (contentElement) {
comments.push({
id: `yt-comment-${index}`,
author: authorElement ? authorElement.textContent.trim() : 'YouTube User',
content: contentElement.textContent.trim(),
timestamp: timestampElement ? timestampElement.textContent.trim() : 'Recently',
likes: likesElement ? parseInt(likesElement.textContent) || 0 : 0,
platform: 'youtube'
});
}
} catch (error) {
console.error('Error extracting YouTube comment:', error);
}
});
}
function extractTwitterComments(comments) {
// Twitter/X comment selectors
const commentElements = document.querySelectorAll('[data-testid="tweet"]');
commentElements.forEach((element, index) => {
try {
const authorElement = element.querySelector('[data-testid="User-Name"]');
const contentElement = element.querySelector('[data-testid="tweetText"]');
const timestampElement = element.querySelector('time');
const likesElement = element.querySelector('[data-testid="like"]');
if (contentElement) {
comments.push({
id: `twitter-comment-${index}`,
author: authorElement ? authorElement.textContent.split('·')[0].trim() : 'Twitter User',
content: contentElement.textContent.trim(),
timestamp: timestampElement ? timestampElement.getAttribute('datetime') : 'Recently',
likes: likesElement ? parseInt(likesElement.textContent) || 0 : 0,
platform: 'twitter'
});
}
} catch (error) {
console.error('Error extracting Twitter comment:', error);
}
});
}
function extractInstagramComments(comments) {
// Instagram comment selectors
const commentElements = document.querySelectorAll('ul > li > div > div > div:nth-child(2)');
commentElements.forEach((element, index) => {
try {
const authorElement = element.querySelector('h3');
const contentElement = element.querySelector('span');
if (contentElement && authorElement) {
comments.push({
id: `ig-comment-${index}`,
author: authorElement.textContent.trim(),
content: contentElement.textContent.trim(),
timestamp: 'Recently', // Instagram doesn't easily show timestamps
likes: 0, // Instagram doesn't easily show like counts
platform: 'instagram'
});
}
} catch (error) {
console.error('Error extracting Instagram comment:', error);
}
});
}
function extractLinkedinComments(comments) {
// LinkedIn comment selectors
const commentElements = document.querySelectorAll('.comments-comment-item');
commentElements.forEach((element, index) => {
try {
const authorElement = element.querySelector('.comments-post-meta__name-text');
const contentElement = element.querySelector('.comments-comment-item__main-content');
const timestampElement = element.querySelector('.comments-comment-item__timestamp');
if (contentElement) {
comments.push({
id: `linkedin-comment-${index}`,
author: authorElement ? authorElement.textContent.trim() : 'LinkedIn User',
content: contentElement.textContent.trim(),
timestamp: timestampElement ? timestampElement.textContent.trim() : 'Recently',
likes: 0, // LinkedIn doesn't easily show like counts
platform: 'linkedin'
});
}
} catch (error) {
console.error('Error extracting LinkedIn comment:', error);
}
});
}
function extractGenericComments(comments) {
// Generic comment selectors that might work across different platforms
const possibleCommentSelectors = [
'.comment',
'[class*="comment"]',
'[id*="comment"]',
'.review',
'[class*="review"]',
'[class*="post"]',
'[class*="message"]'
];
for (const selector of possibleCommentSelectors) {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) {
elements.forEach((element, index) => {
// Try to find text content that looks like a comment
const textContent = element.textContent.trim();
if (textContent.length > 10 && textContent.length < 1000) {
comments.push({
id: `generic-comment-${index}`,
author: 'User',
content: textContent,
timestamp: 'Recently',
likes: 0,
platform: 'other'
});
}
});
// If we found comments with this selector, no need to try others
if (comments.length > 0) break;
}
}
}
// Listen for messages from the sidebar
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'GET_COMMENTS') {
const comments = extractComments();
// Limit the number of comments based on settings
chrome.storage.sync.get(['maxComments'], (result) => {
const maxComments = result.maxComments || 50;
const limitedComments = comments.slice(0, maxComments);
// Send the comments back to the sidebar
chrome.runtime.sendMessage({
type: 'COMMENTS_CAPTURED',
comments: limitedComments
});
});
}
return true;
});
// Initial extraction when the content script loads
setTimeout(() => {
const comments = extractComments();
chrome.storage.sync.get(['maxComments'], (result) => {
const maxComments = result.maxComments || 50;
const limitedComments = comments.slice(0, maxComments);
chrome.runtime.sendMessage({
type: 'COMMENTS_CAPTURED',
comments: limitedComments
});
});
}, 1000);