Sam20202's picture
Initial deploy
0533780
// content.js β€” Injected into every page
// Manages the screen selection overlay and sidebar panel
let overlayActive = false;
let sidebarFrame = null;
// ── Listen for messages from background / popup ───────────────────────────────
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
if (msg.type === "START_SELECTION") {
if (!overlayActive) startSelection();
sendResponse({ ok: true });
return false;
}
if (msg.type === "SHOW_SIDEBAR") {
showSidebar({});
return false;
}
if (msg.type === "SHOW_RESULT") {
showSidebar(msg.data);
return false;
}
});
// ── Selection overlay ─────────────────────────────────────────────────────────
function startSelection() {
overlayActive = true;
// Dim the page
const overlay = document.createElement("div");
overlay.id = "glmocr-overlay";
// Crosshair hint
const hint = document.createElement("div");
hint.id = "glmocr-hint";
hint.textContent = "Drag to select text region β€” Press Esc to cancel";
overlay.appendChild(hint);
// Selection box
const selBox = document.createElement("div");
selBox.id = "glmocr-selbox";
overlay.appendChild(selBox);
document.body.appendChild(overlay);
let startX = 0, startY = 0, isDragging = false;
function onMouseDown(e) {
if (e.button !== 0) return;
isDragging = true;
startX = e.clientX;
startY = e.clientY;
selBox.style.cssText = `left:${startX}px; top:${startY}px; width:0; height:0; display:block`;
hint.style.opacity = "0";
e.preventDefault();
}
function onMouseMove(e) {
if (!isDragging) return;
const x = Math.min(e.clientX, startX);
const y = Math.min(e.clientY, startY);
const w = Math.abs(e.clientX - startX);
const h = Math.abs(e.clientY - startY);
selBox.style.cssText = `left:${x}px; top:${y}px; width:${w}px; height:${h}px; display:block`;
}
function onMouseUp(e) {
if (!isDragging) return;
isDragging = false;
const x = Math.min(e.clientX, startX);
const y = Math.min(e.clientY, startY);
const w = Math.abs(e.clientX - startX);
const h = Math.abs(e.clientY - startY);
cleanup();
if (w < 10 || h < 10) {
showToast("Selection too small β€” try again.");
return;
}
const dpr = window.devicePixelRatio || 1;
const rect = {
x: x + window.scrollX,
y: y + window.scrollY,
width: w,
height: h,
dpr,
};
runOcr(rect);
}
function onKeyDown(e) {
if (e.key === "Escape") {
cleanup();
showToast("Cancelled.");
}
}
function cleanup() {
overlayActive = false;
overlay.removeEventListener("mousedown", onMouseDown);
overlay.removeEventListener("mousemove", onMouseMove);
overlay.removeEventListener("mouseup", onMouseUp);
document.removeEventListener("keydown", onKeyDown);
overlay.remove();
}
overlay.addEventListener("mousedown", onMouseDown);
overlay.addEventListener("mousemove", onMouseMove);
overlay.addEventListener("mouseup", onMouseUp);
document.addEventListener("keydown", onKeyDown);
}
// ── Send region to background for capture + OCR ───────────────────────────────
function runOcr(rect) {
// Show a loading sidebar immediately
showSidebar({ loading: true });
chrome.runtime.sendMessage({ type: "CAPTURE_REGION", rect }, (response) => {
if (chrome.runtime.lastError) {
showSidebar({ error: chrome.runtime.lastError.message });
return;
}
if (response.success) {
showSidebar(response);
} else {
showSidebar({ error: response.error });
}
});
}
// ── Sidebar panel ─────────────────────────────────────────────────────────────
function showSidebar(data) {
// Remove existing sidebar if any
if (sidebarFrame) sidebarFrame.remove();
const frame = document.createElement("iframe");
frame.id = "glmocr-sidebar";
frame.src = chrome.runtime.getURL("sidebar.html");
document.body.appendChild(frame);
sidebarFrame = frame;
// Wait for iframe to load, then send data
frame.onload = () => {
frame.contentWindow.postMessage({ type: "SIDEBAR_DATA", data }, "*");
};
// Close button via message from sidebar
window.addEventListener("message", (e) => {
if (e.data?.type === "CLOSE_SIDEBAR") {
frame.remove();
sidebarFrame = null;
}
if (e.data?.type === "START_NEW_SELECTION") {
frame.remove();
sidebarFrame = null;
startSelection();
}
});
}
// ── Toast notification ────────────────────────────────────────────────────────
function showToast(msg) {
const existing = document.getElementById("glmocr-toast");
if (existing) existing.remove();
const toast = document.createElement("div");
toast.id = "glmocr-toast";
toast.textContent = msg;
document.body.appendChild(toast);
setTimeout(() => toast?.remove(), 3000);
}