Skip to content

Commit d4e35ef

Browse files
committed
Start making it so you can refrence other scripts
1 parent 20b6a1f commit d4e35ef

File tree

6 files changed

+127
-20
lines changed

6 files changed

+127
-20
lines changed

src/ai_dom_editor/editor/helpers/api_handler.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,19 @@ export class ApiHandler {
167167
return { 'Authorization': `Bearer ${apiKey}` };
168168
}
169169

170+
// Handle Gemma models specifically
171+
const isGemma = modelId.includes('gemma') ||
172+
(provider.includes('google') && modelId.includes('gemma'));
173+
174+
if (isGemma) {
175+
return {
176+
'Authorization': `Bearer ${apiKey}`,
177+
'Content-Type': 'application/json'
178+
};
179+
}
180+
170181
// Gemini API uses x-goog-api-key header
171-
if (modelId.includes('gemini') || modelId.includes('gemma') || provider.includes('gemini')) {
182+
if (modelId.includes('gemini') || provider.includes('gemini')) {
172183
return { 'x-goog-api-key': apiKey };
173184
}
174185

@@ -280,7 +291,12 @@ Your response is only the JavaScript code.`;
280291

281292
// build messages depending on heuristics (some providers expect system+user, others expect just user)
282293
const provider = (modelConfig.provider || '').toLowerCase();
283-
const isGoogleish = !provider.includes('aimlapi') && (modelId.toLowerCase().includes('gemini') || modelId.toLowerCase().includes('gemma') || provider.includes('google') || provider.includes('vertex'));
294+
const isGemma = modelId.toLowerCase().includes('gemma');
295+
const isGoogleish = !provider.includes('aimlapi') &&
296+
!isGemma &&
297+
(modelId.toLowerCase().includes('gemini') ||
298+
provider.includes('google') ||
299+
provider.includes('vertex'));
284300
const isAnthropic = provider.includes('anthropic') || modelId.toLowerCase().includes('claude');
285301

286302
// prefer settings on per-model config, fallback to global
@@ -289,7 +305,17 @@ Your response is only the JavaScript code.`;
289305

290306
// Construct request body for common Chat completions patterns (best-effort)
291307
let requestBody;
292-
if (isGoogleish) {
308+
if (isGemma) {
309+
// Format for Gemma models
310+
requestBody = {
311+
model: modelId,
312+
messages: [
313+
{ role: 'user', content: `${systemPrompt}\n\n${userMessage}` }
314+
],
315+
temperature: temperature,
316+
max_tokens: max_tokens
317+
};
318+
} else if (isGoogleish) {
293319
// Gemini uses a different API format than OpenAI
294320
// Format: { contents: [{ parts: [{ text: "..." }] }] }
295321
const combinedPrompt = `${systemPrompt}\n\n${userMessage}`;

src/ai_dom_editor/editor/helpers/event_handler.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ export class EventHandler {
77
}
88

99
setupEventListeners() {
10-
this.editor.elements.userInput.addEventListener('input', () => {
10+
this.editor.elements.userInput.addEventListener('input', (e) => {
1111
this.editor.uiManager.autoResize(this.editor.elements.userInput);
1212
this.editor.elements.sendBtn.disabled = !this.editor.elements.userInput.value.trim();
13+
14+
const value = e.target.value;
15+
if (value.endsWith('@')) {
16+
this.editor.uiManager.showScriptSelector(e.target);
17+
} else if (!value.includes('@')) {
18+
this.editor.uiManager.hideScriptSelector();
19+
}
1320
});
1421

1522
this.editor.elements.userInput.addEventListener('keydown', (e) => {

src/ai_dom_editor/editor/helpers/ui_manager.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,38 @@ export class UIManager {
196196
this.editor.elements.welcomeMessage.style.display = 'none';
197197
}
198198
}
199+
200+
async showScriptSelector(input) {
201+
this.hideScriptSelector();
202+
const scripts = await this.editor.userscriptHandler.getAllScripts();
203+
if (!scripts || scripts.length === 0) return;
204+
205+
const selector = document.createElement('div');
206+
selector.className = 'script-selector';
207+
208+
scripts.forEach(scriptName => {
209+
const item = document.createElement('div');
210+
item.className = 'script-item';
211+
item.textContent = scriptName;
212+
item.addEventListener('click', () => {
213+
const atIndex = input.value.lastIndexOf('@');
214+
input.value = input.value.substring(0, atIndex + 1) + scriptName + ' ';
215+
this.hideScriptSelector();
216+
input.focus();
217+
});
218+
selector.appendChild(item);
219+
});
220+
221+
document.body.appendChild(selector);
222+
const rect = input.getBoundingClientRect();
223+
selector.style.top = `${rect.top - selector.offsetHeight}px`;
224+
selector.style.left = `${rect.left}px`;
225+
}
226+
227+
hideScriptSelector() {
228+
const selector = document.querySelector('.script-selector');
229+
if (selector) {
230+
selector.remove();
231+
}
232+
}
199233
}

src/ai_dom_editor/editor/helpers/userscript_handler.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ export class UserscriptHandler {
1919
});
2020
}
2121

22+
async getAllScripts() {
23+
return new Promise((resolve, reject) => {
24+
chrome.runtime.sendMessage({ action: 'getAllScripts' }, (response) => {
25+
if (chrome.runtime.lastError) {
26+
return reject(new Error(chrome.runtime.lastError.message));
27+
}
28+
if (response.error) {
29+
return reject(new Error(response.error));
30+
}
31+
resolve(response.scripts);
32+
});
33+
});
34+
}
35+
2236
async createUserscript(code) {
2337
try {
2438
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

src/assets/styles/ai/ai_dom_editor.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,4 +539,25 @@ button svg {
539539
flex-shrink: 0;
540540
width: 38px;
541541
height: 38px;
542+
}
543+
544+
.script-selector {
545+
position: absolute;
546+
z-index: 1000;
547+
background: var(--bg-tertiary);
548+
border: 1px solid var(--border-primary);
549+
border-radius: 0.5rem;
550+
max-height: 150px;
551+
overflow-y: auto;
552+
width: 250px;
553+
}
554+
555+
.script-item {
556+
padding: 0.5rem 0.75rem;
557+
cursor: pointer;
558+
font-size: 0.8125rem;
559+
}
560+
561+
.script-item:hover {
562+
background: var(--bg-hover);
542563
}

src/background/background.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -548,52 +548,57 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
548548
updateAllTabBadges();
549549
sendResponse({ success: true });
550550
},
551-
552551
createScript: () => {
553552
handleScriptCreation(message.data.url, message.data.template);
554553
},
555-
556554
contentScriptReady: () => {
557555
if (sender.tab?.id) {
558556
state.executedScripts.set(sender.tab.id, new Set());
559557
}
560558
},
561-
562559
greasyForkInstall: () => {
563560
handleGreasyForkInstall(message.url);
564561
},
565-
566562
openAISettings: () => {
567563
chrome.tabs.create({ url: chrome.runtime.getURL("ai_dom_editor/settings/ai_settings.html") });
568564
sendResponse({ success: true });
569565
},
570-
571566
createScriptFromAI: () => {
572567
handleAIScriptCreation(message.script, message.url);
573568
sendResponse({ success: true });
574569
},
575-
576570
aiSettingsUpdated: () => {
577-
// Notify any open AI editors
578571
chrome.runtime.sendMessage({ action: 'aiConfigUpdated' }).catch(() => {});
579572
sendResponse({ success: true });
580573
},
574+
};
575+
576+
const handler = messageHandlers[message.action];
577+
if (handler) {
578+
handler();
579+
return false;
580+
}
581581

582-
getScriptContent: async ({ scriptName }) => {
582+
if (message.action === 'getScriptContent') {
583+
(async () => {
583584
const { scripts = [] } = await chrome.storage.local.get("scripts");
584-
const script = scripts.find(s => s.name === scriptName);
585+
const script = scripts.find(s => s.name === message.scriptName);
585586
if (script) {
586587
sendResponse({ code: script.code });
587588
} else {
588-
sendResponse({ error: `Script not found: ${scriptName}` });
589+
sendResponse({ error: `Script not found: ${message.scriptName}` });
589590
}
590-
},
591-
};
591+
})();
592+
return true;
593+
}
592594

593-
const handler = messageHandlers[message.action];
594-
if (handler) {
595-
handler();
596-
return false;
595+
if (message.action === 'getAllScripts') {
596+
(async () => {
597+
const { scripts = [] } = await chrome.storage.local.get("scripts");
598+
const scriptNames = scripts.map(s => s.name);
599+
sendResponse({ scripts: scriptNames });
600+
})();
601+
return true;
597602
}
598603

599604
sendResponse({ error: "Unknown action" });

0 commit comments

Comments
 (0)