-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.ts
More file actions
137 lines (111 loc) Β· 4.32 KB
/
Copy pathindex.ts
File metadata and controls
137 lines (111 loc) Β· 4.32 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
import { TweetData, MessagePayload } from '../types';
import { isOnTweetDetailPage, extractMainTweetData, extractTweetData } from './extractors';
console.log('π X Comment Helper content script loaded');
console.log('π Current URL:', window.location.href);
// Send tweet data to extension
function sendTweetData(tweetData: TweetData) {
console.log('βοΈ Sending tweet data to extension:', tweetData);
const message: MessagePayload = {
type: 'TWEET_CLICKED',
data: tweetData
};
chrome.runtime.sendMessage(message)
.then(() => console.log('β
Message sent successfully'))
.catch(err => console.error('β Failed to send message:', err));
}
// Auto-detect and send tweet data on detail page
function autoDetectTweetOnDetailPage() {
if (!isOnTweetDetailPage()) {
console.log('βΉοΈ Not on tweet detail page, skipping auto-detect');
return;
}
console.log('π On tweet detail page, auto-detecting tweet...');
// Wait for DOM to be ready with tweet content
const tryExtract = (attempts = 0) => {
const tweetData = extractMainTweetData();
if (tweetData && tweetData.text) {
sendTweetData(tweetData);
} else if (attempts < 5) {
// Retry up to 5 times with 500ms delay (for dynamic content)
console.log(`β³ Tweet not found yet, retrying... (${attempts + 1}/5)`);
setTimeout(() => tryExtract(attempts + 1), 500);
} else {
console.warn('β οΈ Could not extract tweet data after 5 attempts');
}
};
tryExtract();
}
// Track URL changes for SPA navigation
let lastUrl = window.location.href;
function handleUrlChange() {
if (window.location.href !== lastUrl) {
console.log('π URL changed:', lastUrl, 'β', window.location.href);
lastUrl = window.location.href;
// When navigating to a tweet detail page, auto-detect the tweet
setTimeout(autoDetectTweetOnDetailPage, 500);
}
}
// Wait for page to be ready
function initContentScript() {
console.log('β³ Initializing content script...');
// Check if tweets are present
const checkTweets = () => {
const tweets = document.querySelectorAll('article[data-testid="tweet"]');
console.log(`π Found ${tweets.length} tweets on page`);
if (tweets.length === 0 && isOnTweetDetailPage()) {
console.log('π On tweet detail page (no article elements expected)');
} else if (tweets.length === 0) {
console.log('β οΈ No tweets found yet, they may load dynamically');
}
};
// Initial check
checkTweets();
// Check again after a delay (for dynamic content)
setTimeout(checkTweets, 2000);
// Auto-detect tweet on detail page (initial load)
autoDetectTweetOnDetailPage();
// Watch for URL changes (SPA navigation)
const observer = new MutationObserver(handleUrlChange);
observer.observe(document.body, { childList: true, subtree: true });
// Listen for clicks on tweet articles (for timeline view)
document.addEventListener('click', (event) => {
console.log('π Click detected');
const target = event.target as Element;
// Try to find article with tweet data-testid
let article = target.closest('article[data-testid="tweet"]');
// Fallback: try to find any article element
if (!article) {
article = target.closest('article');
if (article) {
console.log('β οΈ Found article without data-testid="tweet"');
}
}
if (article) {
console.log('β
Article element found:', article);
const tweetData = extractTweetData(article);
if (tweetData && tweetData.text) {
sendTweetData(tweetData);
} else {
console.warn('β οΈ No valid tweet data extracted');
}
} else {
// On detail page, clicking anywhere might mean interacting with the main tweet
if (isOnTweetDetailPage()) {
console.log('βΉοΈ Click on detail page, checking for main tweet');
const tweetData = extractMainTweetData();
if (tweetData && tweetData.text) {
sendTweetData(tweetData);
}
} else {
console.log('βΉοΈ Click was not on a tweet');
}
}
}, true); // Use capture phase to catch clicks early
console.log('β
Content script initialized successfully');
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initContentScript);
} else {
initContentScript();
}