From bb06e0e58dcb90eceede6f0b05743fdccc8f51af Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Tue, 1 Sep 2026 20:38:17 +0900 Subject: fix: options page never ran due to missing export; unify settings handling Root cause of the broken options page (audit finding): - options.js imported CONTEXT_PRESETS from settings-schema.js, but that module never exported it. A named-import mismatch in ES modules is a SyntaxError, so the entire options page script silently never executed. This is why the settings page rendered its static HTML but was dead: no language options, no model list, no save handler. Fixes - options.js: import CONTEXT_PRESETS from shared/constants.js (where it is defined) instead of settings-schema.js - options.js: save flow now merges the validated form over the stored settings (sanitize again) so fields saved by the popup in the meantime are preserved instead of being dropped - popup.js: populate language options inside loadSettings and sanitize settings before every save, matching the options page behavior - settings-schema.js: add normalizeOllamaHost() and use it in sanitizeSettings so trailing-slash variants are stored identically - content.js: consolidate popover state - remove the duplicate outer lastSourceText and keep regenerate source inside the popover module; regenerate now calls portClient.translate directly Test hardening (would have caught the original bug) - tests/ui-smoke-tests.js: new smoke tests that install a fake browser API, run the real popup.js / options.js page scripts as ES modules against representative markup, and assert that language options are populated, the model select is filled from the mocked model list, and the stored host is reflected. The runner result elements are preserved across the sandboxed DOM swap - test.html: include the smoke test module Results: 73 passed, 0 failed (71 existing + 2 smoke). dist rebuilt. --- src/content/content.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'src/content') diff --git a/src/content/content.js b/src/content/content.js index e1e6823..fa5f416 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -56,8 +56,6 @@ let currentSelectionRect = null; /** @type {string|null} id of the request the popover currently shows */ let activeRequestId = null; - /** @type {string|null} source text of the last request (for regenerate) */ - let lastSourceText = null; // --------------------------------------------------------------------- // 2. Selection controller @@ -364,7 +362,7 @@ }); regenerateButton.addEventListener('click', () => { if (localLastSourceText) { - requestTranslation(localLastSourceText); + portClient.translate(localLastSourceText); } }); } @@ -551,7 +549,6 @@ const p = connect(); const requestId = generateRequestId(); activeRequestId = requestId; - lastSourceText = text; popover.beginRequest(text, currentSelectionRect || { left: 16, top: 16, bottom: 40, right: 356 }); p.postMessage({ type: CONTENT_TO_BG.TRANSLATE, requestId, text }); }, @@ -587,14 +584,6 @@ portClient.translate(selection.text); } - /** - * Request a translation for an arbitrary source text (regenerate). - * @param {string} sourceText - */ - function requestTranslation(sourceText) { - portClient.translate(sourceText); - } - // --------------------------------------------------------------------- // Enabled state (storage.local, EN-01/EN-02) // --------------------------------------------------------------------- -- cgit v1.2.3