-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.js
More file actions
123 lines (108 loc) · 4.45 KB
/
Copy pathcontent.js
File metadata and controls
123 lines (108 loc) · 4.45 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
// content.js
/**
* Extracts the TV show name from the current page using the method
* defined in the site configuration (Regex or XPath).
* @param {object} site - The configuration object for the matched site.
* @returns {string|null} The extracted name or null if not found.
*/
function extractName(site) {
try {
if (site.nameExtractionRegex) {
const title = document.title;
const match = title.match(new RegExp(site.nameExtractionRegex));
if (match && match[1]) return match[1].trim();
} else if (site.nameExtractionXpath) {
const result = document.evaluate(site.nameExtractionXpath, document, null, XPathResult.STRING_TYPE, null);
if (result.stringValue) return result.stringValue.trim();
}
} catch (e) {
console.error('SickChill Plugin: Error during name extraction:', e);
}
return null;
}
/**
* Injects the "Add to SickChill" icon and link onto the page.
* @param {HTMLElement} targetElement - The DOM element to inject the icon next to.
* @param {string} title - The extracted TV show title.
*/
function performInjection(targetElement, title) {
// Avoid duplicate injections.
if (targetElement.previousSibling && targetElement.previousSibling.id === 'sickchill-add-icon') return;
const link = document.createElement('a');
link.id = 'sickchill-add-icon';
link.title = `Add "${title}" to SickChill`;
link.style.cursor = 'pointer';
// When clicked, prevent default link behavior and send a message to the background script.
link.onclick = (e) => {
e.preventDefault();
e.stopPropagation();
chrome.runtime.sendMessage({
action: "directToAddShowPage",
name: title
});
};
const icon = document.createElement('img');
icon.src = chrome.runtime.getURL('images/SC.png');
icon.style.height = '1em';
icon.style.width = 'auto';
icon.style.marginRight = '8px';
icon.style.verticalAlign = 'middle';
link.appendChild(icon);
targetElement.parentNode.insertBefore(link, targetElement);
console.log(`SickChill Plugin: Icon injected for "${title}".`);
}
/**
* Finds the matching site configuration for the current URL.
*/
function initialize() {
chrome.storage.local.get({ sites: [] }, (result) => {
if (chrome.runtime.lastError) return;
const matchingSite = result.sites.find(site => {
// Check if site is enabled (undefined is treated as enabled for backward compatibility)
if (site.enabled === false) {
return false;
}
if (site.host && window.location.href.includes(site.host)) {
// If a URL regex is provided, it must also match.
if (site.urlRegex) {
try {
return new RegExp(site.urlRegex, 'i').test(window.location.href);
}
catch (e) {
return false;
}
}
return true;
}
return false;
});
if (matchingSite) {
waitForElementsAndInject(matchingSite);
}
});
}
/**
* Periodically checks for the required elements on the page before injecting the icon.
* This handles pages that load content dynamically.
* @param {object} site - The configuration for the matched site.
*/
function waitForElementsAndInject(site) {
let attempts = 0;
const maxAttempts = 60; // Try for 15 seconds (60 * 250ms).
const intervalId = setInterval(() => {
if (attempts++ >= maxAttempts) {
clearInterval(intervalId);
return;
}
// If a content regex is provided, check if the page body contains the text.
if (site.contentRegex && !new RegExp(site.contentRegex, 'i').test(document.body.innerText)) return;
const extractedName = extractName(site);
const injectionTarget = document.evaluate(site.injectionXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
// Once both the name and target element are found, perform the injection.
if (extractedName && injectionTarget) {
clearInterval(intervalId);
performInjection(injectionTarget, extractedName);
}
}, 250);
}
initialize();