Skip to content

fix(plugins): restore ChatGPT formula copy in Edge - #911

Merged
Nagi-ovo merged 3 commits into
Nagi-ovo:mainfrom
shallowaria:codex/fix-edge-chatgpt-formula-copy-clean
Aug 7, 2026
Merged

fix(plugins): restore ChatGPT formula copy in Edge#911
Nagi-ovo merged 3 commits into
Nagi-ovo:mainfrom
shallowaria:codex/fix-edge-chatgpt-formula-copy-clean

Conversation

@shallowaria

@shallowaria shallowaria commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #909

Clean replacement for #910. This PR carries the final fix on the current main; the only follow-up commit addresses CodeRabbit's sync-failure review finding.

Description / 描述

Formula Copy had two independent failures on ChatGPT/Edge:

  • Edge could grant the optional ChatGPT host permission without reconciling the dynamically registered plugin content script. After a successful grant, the popup now asks the background service to run the existing serialized registration sync, while keeping permissions.onAdded as the Chrome popup-close fallback.
  • Current ChatGPT KaTeX markup can omit MathML annotations. Formula Copy now reads the nearest data-math-source value and recognizes .katex-display as block math, while preserving the legacy annotation paths used by Claude, older ChatGPT markup, Gemini, and AI Studio.

The PR adds realistic ChatGPT inline/block DOM regression coverage, permission-registration routing tests, and a regression note. The follow-up review fix keeps the required-access repair action available when background reconciliation fails and adds a rejected-message test.

Related Issue / 相关 Issue

Fixes #909

Visual Proof / 可视化证据

The contributor manually verified the rebuilt dist_chrome_dev package on the real ChatGPT formula from #909: hover styling appeared and clicking the formula copied the expected LaTeX successfully.

visual-prove.mp4

Browser Testing / 浏览器测试

Current tested head / 当前验证提交: a32b97ea2b379bf11c32d26b35dfb16c36339dc7

Full-suite and cross-browser build baseline / 全量测试及跨浏览器构建基线: e591cab1c4385fbfbae362da774ebed3b822f676

Browser / version Scenario and result / 场景与结果 Evidence / 证据
Chrome on Windows (exact version not captured) On predecessor implementation commit 0788f16181e33ca77346eef5787c0d204a4f8278, loaded the freshly rebuilt dist_chrome_dev, refreshed the real ChatGPT conversation, and clicked current data-math-source KaTeX. Copy succeeded with the configured LaTeX delimiters. Linked recording above

Missing checks and owner / 缺失检查与负责人:

  • Needs an exact-a32b97ea Chrome live reload; owner: @shallowaria. The linked live recording predates the clean branch and follow-up review fix.
  • Needs Edge live verification of optional host grant, dynamic registration, and ChatGPT formula copy; owner: @shallowaria.
  • Needs Firefox live plugin lifecycle/formula-copy smoke; owner: @shallowaria or a maintainer with Firefox access.
  • Needs Safari live plugin lifecycle/formula-copy smoke; owner: @shallowaria or a maintainer with Safari access.
  • These checks remain explicit because builtin plugin changes require Chrome, Edge, Firefox, and Safari live coverage before merge.

Commands run / 已运行命令:

  • Prettier on all 9 changed paths
  • bun run lint — 0 errors; 209 existing warnings; no resulting edits
  • bun run typecheck
  • bun run i18n:check — 10 locales, 693 keys
  • Focused regression suite at a32b97ea — 3 files, 30 tests
  • bunx vitest run --exclude scripts/__tests__/verify-release-privacy.test.ts --testTimeout 20000 --hookTimeout 30000 --silent — 277 files, 2597 tests
  • bun run build:all — Chrome, Firefox, and Safari builds passed; Safari resource wiring passed
  • bun run build:edge — Edge production code build and manifest preparation passed; dist_edge was produced
  • bun run docs:build
  • Follow-up review-fix verification at a32b97ea: targeted Prettier; bun run typecheck; bun run lint (0 errors, 209 existing warnings); focused suite (3 files, 30 tests); bun run build:chrome
  • git diff --check origin/main...HEAD

Commands not completed and reason / 未完成命令及原因:

  • bun run verify:pr was not completed as one command on this Windows checkout because the repository symlink-only privacy test is incompatible here. Its applicable formatting, lint, typecheck, test, browser-build, i18n, and diff gates were run separately.
  • scripts/__tests__/verify-release-privacy.test.ts requires repository symlinks unavailable in this Windows checkout; the full test run excluded only that file.
  • bun run build:edge reached the final packaging step, then failed because the external zip executable is unavailable on Windows. CI's Edge build remains required.
  • The normal commit hook failed in this Windows environment with Cannot access 'default' before initialization; both commits were created with --no-verify only after the targeted Prettier checks and the verification suite above passed.
  • GitHub CLI is not installed, so the branch was pushed with Git and this draft PR was created and verified through the authenticated GitHub web UI as @shallowaria.

Checklist / 检查清单

  • If I used an agent, I discussed the requirement, affected scope, and verification plan clearly. / 如果使用了 Agent,我已讨论清楚需求、影响范围和验证方式。
  • I have manually verified that the feature works as intended. / 我已手动验证功能按预期工作。
  • For UI/behavior changes, I have included visual proof after verification. / 对于 UI/行为改动,我已在验证后提供可视化证据。
  • I have confirmed that this PR does not break existing functionality. / 我已确认此 PR 不会破坏原有功能。
  • This PR focuses on one issue or one coherent change. / 此 PR 只聚焦一个问题或一个清晰完整的改动。
  • I ran the standard local gates or listed every omitted command and reason above. / 我已运行标准本地检查,或在上方逐项说明未运行命令及原因。
  • I added/updated regression tests for behavior changes. / 行为改动已添加或更新回归测试。
  • I listed the affected browsers actually tested and identified every required follow-up owner. / 我已列出实际测试的受影响浏览器,并标明所有必需补测的负责人。

Summary by CodeRabbit

Bug Fixes

  • Improved copying of inline and block LaTeX formulas from current ChatGPT and Claude pages, including formulas without MathML annotations.
  • Improved recognition of display-mode formulas.

Plugin Improvements

  • Plugin content scripts now synchronize after permissions are granted or repaired.
  • Plugin enablement rolls back when required permissions are denied.

Tests

  • Added coverage for formula copying and plugin synchronization flows.

Fixes Nagi-ovo#909

Co-authored-by: Codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4aae0d4a-0621-4c9b-9f3f-d367fe629def

📥 Commits

Reviewing files that changed from the base of the PR and between e591cab and 16c1d04.

📒 Files selected for processing (3)
  • .github/docs/REGRESSION_NOTES.md
  • src/pages/popup/components/PluginManager.tsx
  • src/pages/popup/components/__tests__/PluginManager.test.tsx

📝 Walkthrough

Walkthrough

The PR fixes ChatGPT formula copying without MathML annotations and adds explicit plugin content-script synchronization after host permission changes. It adds routing, permission-flow, and regression-test coverage.

Changes

ChatGPT Formula Copy

Layer / File(s) Summary
KaTeX extraction and display detection
src/features/formulaCopy/FormulaCopyService.ts
Formula extraction reads trimmed data-math-source values before legacy annotations. Display detection recognizes .katex-display.
Current ChatGPT fixtures and regression coverage
src/features/formulaCopy/FormulaCopyService.test.ts, .github/docs/REGRESSION_NOTES.md
Tests cover block formulas with $$...$$ and inline formulas with $...$ when MathML is absent. The regression note documents the markup and fallback behavior.

Plugin Content-Script Synchronization

Layer / File(s) Summary
Synchronization message routing
src/features/plugins/runtime/messages.ts, src/pages/background/runtimeMessageRouting.ts, src/pages/background/index.ts, src/pages/background/__tests__/runtimeMessageRouting.test.ts
The background service accepts gv.plugins.syncContentScripts, awaits serialized synchronization, and returns { ok: true }.
Permission-driven synchronization
src/pages/popup/components/PluginManager.tsx, src/pages/popup/components/__tests__/PluginManager.test.tsx
Plugin enabling persists state before permission prompts, rolls back denied grants, and requests synchronization after approved grants and access repairs. Tests verify message ordering and failed-reconciliation handling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PluginManager
  participant runtime.sendMessage
  participant BackgroundService
  participant syncPluginContentScripts
  PluginManager->>runtime.sendMessage: Send gv.plugins.syncContentScripts after permission approval
  runtime.sendMessage->>BackgroundService: Route synchronization request
  BackgroundService->>syncPluginContentScripts: Await serialized registration reconciliation
  syncPluginContentScripts-->>BackgroundService: Complete synchronization
  BackgroundService-->>runtime.sendMessage: Return { ok: true }
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #909 by restoring ChatGPT formula detection, copying, and Edge content-script synchronization.
Out of Scope Changes check ✅ Passed The code, tests, and regression note remain focused on the ChatGPT Formula Copy failure described in issue #909.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly and concisely identifies the primary fix: restoring ChatGPT formula copying in Edge.
Description check ✅ Passed The description covers the goal, scope, tests, visual proof, browser gaps, owners, and verification limitations in the required sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

@shallowaria

Copy link
Copy Markdown
Contributor Author

@codex review

@shallowaria

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/popup/components/PluginManager.tsx`:
- Around line 37-43: The helper requestPluginContentScriptSync must report
whether browser.runtime.sendMessage succeeded instead of suppressing failures.
Update handleGrantRequiredAccess to remove plugin.id from missingPermissionIds
only when synchronization succeeds, preserving the repair action otherwise, and
add a test covering a rejected runtime.sendMessage.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: da2f19d1-d0da-45a7-a342-5359fbc72974

📥 Commits

Reviewing files that changed from the base of the PR and between 720db0b and e591cab.

📒 Files selected for processing (9)
  • .github/docs/REGRESSION_NOTES.md
  • src/features/formulaCopy/FormulaCopyService.test.ts
  • src/features/formulaCopy/FormulaCopyService.ts
  • src/features/plugins/runtime/messages.ts
  • src/pages/background/__tests__/runtimeMessageRouting.test.ts
  • src/pages/background/index.ts
  • src/pages/background/runtimeMessageRouting.ts
  • src/pages/popup/components/PluginManager.tsx
  • src/pages/popup/components/__tests__/PluginManager.test.tsx

Comment thread src/pages/popup/components/PluginManager.tsx Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: e591cab1c4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

shallowaria and others added 2 commits August 8, 2026 00:40
Keep the required-access repair action visible until the background confirms content-script reconciliation.

Co-authored-by: Codex <codex@users.noreply.github.com>

@Nagi-ovo Nagi-ovo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — verified the extraction priority (Gemini data-math → ChatGPT data-math-source → AI Studio/Claude annotations), the .katex-display block detection stays correct for Claude, and the gv.plugins.syncContentScripts type is properly added to the background routing allow-list with tests. Resolved the REGRESSION_NOTES append conflict against main on the branch. Thanks for the clean replacement PR!

@shallowaria
shallowaria marked this pull request as ready for review August 7, 2026 17:14
@Nagi-ovo
Nagi-ovo merged commit fef895c into Nagi-ovo:main Aug 7, 2026
14 of 15 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 16c1d04253

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


if (message?.type === PLUGIN_CONTENT_SCRIPT_SYNC_MESSAGE) {
await syncPluginContentScripts();
sendResponse({ ok: true });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Report plugin sync registration failures

When chrome.scripting.registerContentScripts rejects during doSyncPluginContentScripts, that function catches/logs and resolves, so this new branch still sends { ok: true }. In the Edge permission-repair flow the popup removes the pluginGrantRequiredAccess retry as soon as it sees ok, leaving a granted-but-unregistered plugin (Formula Copy still inert) with no retry path; have the sync return a real success/failure before acknowledging.

AGENTS.md reference: AGENTS.md:L84-L84

Useful? React with 👍 / 👎.

// permissions.onAdded event that normally performs registration.
// Reconcile explicitly while retaining onAdded as Chrome's
// popup-close fallback.
await requestPluginContentScriptSync();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle failed explicit sync after enabling

In the new-host enable path, requestPluginContentScriptSync() is explicitly the Edge fallback, but this result is ignored. If sendMessage fails or the background returns { ok: false } after the user grants the host, the plugin remains enabled from the pre-prompt write, and because the permission is now present the missing-access repair button will not appear; surface or roll back the failed sync instead of returning.

AGENTS.md reference: AGENTS.md:L84-L84

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot mentioned this pull request Aug 9, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Formula Copy does not work on ChatGPT in Microsoft Edge

2 participants