Merge pull request #25 from outis1one/claude/read-repo-YMu21

feat: dynamic content script registration for custom domains
This commit is contained in:
Outis
2026-03-27 00:42:17 -04:00
committed by GitHub
2 changed files with 54 additions and 1 deletions
+45
View File
@@ -61,6 +61,44 @@ api.tabs.onRemoved.addListener((tabId) => {
// --- Dynamic injection for custom domains --- // --- Dynamic injection for custom domains ---
const DYNAMIC_SCRIPT_ID = 'ss-custom-domains';
/**
* Sync the dynamically registered content script with the current
* custom domains list. Uses scripting.registerContentScripts so custom
* domains inject at document_start (like built-in sites) and persist
* across service worker restarts.
*/
async function syncCustomDomainScripts() {
const settings = await Storage.getSettings();
const customDomains = settings.customDomains || [];
// Build match patterns from domains (e.g. "https://my-ai.com" → "https://my-ai.com/*")
const matches = customDomains.map(d => d.replace(/\/$/, '') + '/*');
try {
// Remove existing dynamic script first
await api.scripting.unregisterContentScripts({ ids: [DYNAMIC_SCRIPT_ID] }).catch(() => {});
if (matches.length > 0) {
await api.scripting.registerContentScripts([{
id: DYNAMIC_SCRIPT_ID,
matches,
js: ['src/content/injector.js'],
css: ['src/content/content.css'],
runAt: 'document_start',
allFrames: true,
}]);
}
} catch (e) {
console.warn('[Silent Send] Failed to register custom domain scripts:', e);
}
}
/**
* Inject on an already-open tab for a newly added custom domain.
* Only needed for tabs that were open before the content script was registered.
*/
async function injectOnCustomDomain(tabId, tabUrl) { async function injectOnCustomDomain(tabId, tabUrl) {
const settings = await Storage.getSettings(); const settings = await Storage.getSettings();
const customDomains = settings.customDomains || []; const customDomains = settings.customDomains || [];
@@ -362,6 +400,11 @@ api.storage.onChanged.addListener(async (changes, areaName) => {
const settings = await Storage.getSettings(); const settings = await Storage.getSettings();
await updateIcon(settings); await updateIcon(settings);
// Re-register dynamic content scripts when custom domains change
if (changes.ss_settings && areaName === 'local') {
await syncCustomDomainScripts();
}
// Push to browser.storage.sync when local data changes (same-browser cross-device) // Push to browser.storage.sync when local data changes (same-browser cross-device)
if (areaName === 'local' && settings.browserSync) { if (areaName === 'local' && settings.browserSync) {
await SilentSendSync.pushToSyncStorage(); await SilentSendSync.pushToSyncStorage();
@@ -487,6 +530,7 @@ api.runtime.onInstalled.addListener(async () => {
api.action.setBadgeBackgroundColor({ color: '#6b7280' }); api.action.setBadgeBackgroundColor({ color: '#6b7280' });
const settings = await Storage.getSettings(); const settings = await Storage.getSettings();
await updateIcon(settings); await updateIcon(settings);
await syncCustomDomainScripts();
// Set up alarms on install // Set up alarms on install
await setupAutoSyncAlarm(); await setupAutoSyncAlarm();
await setupOrgPolicyAlarm(); await setupOrgPolicyAlarm();
@@ -496,6 +540,7 @@ api.runtime.onInstalled.addListener(async () => {
(async () => { (async () => {
const settings = await Storage.getSettings(); const settings = await Storage.getSettings();
await updateIcon(settings); await updateIcon(settings);
await syncCustomDomainScripts();
// Check if extension is locked (encrypted data, no cached key) // Check if extension is locked (encrypted data, no cached key)
const locked = await Storage.isLocked(); const locked = await Storage.isLocked();
+9 -1
View File
@@ -620,9 +620,17 @@ function renderDomains() {
btn.addEventListener('click', async () => { btn.addEventListener('click', async () => {
const idx = parseInt(btn.dataset.index, 10); const idx = parseInt(btn.dataset.index, 10);
const domains = settings.customDomains || []; const domains = settings.customDomains || [];
domains.splice(idx, 1); const removed = domains.splice(idx, 1)[0];
settings.customDomains = domains; settings.customDomains = domains;
await Storage.saveSettings({ customDomains: domains }); await Storage.saveSettings({ customDomains: domains });
// Revoke browser permission for the removed domain
if (removed) {
try {
await api.permissions.remove({ origins: [removed + '/*'] });
} catch (e) { /* non-fatal */ }
}
renderDomains(); renderDomains();
}); });
}); });