Skip to content

Add Firefox Extension#330

Closed
ivLis-Studio wants to merge 4 commits into
edwardkim:mainfrom
ivLis-Studio:ivlis-firefox-extension
Closed

Add Firefox Extension#330
ivLis-Studio wants to merge 4 commits into
edwardkim:mainfrom
ivLis-Studio:ivlis-firefox-extension

Conversation

@ivLis-Studio

Copy link
Copy Markdown

Summary

  • Add a Firefox WebExtension package under rhwp-firefox.
  • Use Firefox-compatible Manifest V3 background scripts instead of Chrome service workers.
  • Add Firefox-specific build wiring, content script behavior, options script, and README.
  • Ignore Firefox build output and Node dependency directories.

Validation

  • npm run check in rhwp-firefox
  • npm run build in rhwp-firefox

@ivLis-Studio

Copy link
Copy Markdown
Author

기존 chrome extension 기반으로, codex로 firefox extension 버전으로 포팅 하였습니다.
정상 작동 확인 하였습니다.

@ivLis-Studio ivLis-Studio changed the title [codex] Add Firefox extension package Add Firefox Extension Apr 25, 2026
@ivLis-Studio ivLis-Studio marked this pull request as ready for review April 25, 2026 09:27
Copilot AI review requested due to automatic review settings April 25, 2026 09:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Firefox WebExtension package (rhwp-firefox) that reuses the existing rhwp-studio viewer build output, while wiring Firefox-compatible MV3 background scripts (non–service worker) plus Firefox-specific content-script behavior, build tooling, and documentation.

Changes:

  • Added rhwp-firefox extension package (manifest, background scripts, content script, options script, SW helpers).
  • Added Firefox build pipeline (build.mjs + vite.config.ts) to produce rhwp-firefox/dist by building rhwp-studio and copying shared assets.
  • Updated repo ignore rules to exclude Node deps and Firefox build output.

Reviewed changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
rhwp-firefox/vite.config.ts Vite config to build rhwp-studio into the Firefox extension dist/ output
rhwp-firefox/sw/viewer-launcher.js Helper to open/reuse the viewer tab with URL params
rhwp-firefox/sw/thumbnail-extractor.js JS thumbnail extraction from HWP/HWPX (CFB/ZIP) for hover previews
rhwp-firefox/sw/message-router.js Background message routing for open/fetch/thumbnail/settings
rhwp-firefox/sw/download-observer.js Observes downloads and auto-opens detected HWP/HWPX files
rhwp-firefox/sw/context-menus.js Adds context menu entry for opening HWP/HWPX links
rhwp-firefox/package.json Firefox package scripts/deps for build and validation
rhwp-firefox/package-lock.json Locked dev dependency graph for rhwp-firefox
rhwp-firefox/options.js Options page logic (sync storage + i18n strings)
rhwp-firefox/manifest.json Firefox MV3 manifest using background scripts (module) + permissions/CSP
rhwp-firefox/firefox-compat.js Compatibility shim to expose chrome as browser where needed
rhwp-firefox/content-script.js Firefox content script for link detection, hover cards, prefetch, click interception
rhwp-firefox/build.mjs Build script assembling dist/ from studio build + shared assets + WASM/fonts
rhwp-firefox/background.js Background entrypoint wiring context menus, downloads observer, message router
rhwp-firefox/README.md Build/load instructions and Firefox-specific notes
.gitignore Ignores Node modules and Firefox build output
Files not reviewed (1)
  • rhwp-firefox/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rhwp-firefox/sw/thumbnail-extractor.js Outdated
Comment on lines +268 to +274
// Base64 인코딩
let binary = '';
for (let i = 0; i < data.length; i++) {
binary += String.fromCharCode(data[i]);
}
const base64 = btoa(binary);
const dataUri = `data:${mime};base64,${base64}`;

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

Base64 encoding is done by concatenating to a JS string in a byte-by-byte loop. For multi-megabyte PrvImage streams this is very slow and memory-heavy (quadratic-ish due to repeated string reallocations) and can cause extension jank. Consider switching to a chunked conversion (e.g., process in 32–64KB chunks) or a streaming Blob/FileReader approach.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Comment thread rhwp-firefox/content-script.js Outdated
Comment on lines +312 to +323
function prefetchThumbnails() {
setTimeout(() => {
const anchors = document.querySelectorAll('a[href]');
for (const anchor of anchors) {
if (!isHwpLink(anchor)) continue;
if (anchor.getAttribute('data-hwp-thumbnail')) continue;
if (thumbnailCache.has(anchor.href)) continue;
prefetchQueue.push(anchor.href);
}
prefetchQueue = [...new Set(prefetchQueue)];
drainPrefetchQueue();
}, 1000);

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

The automatic thumbnail prefetch queues every detected HWP/HWPX link and triggers background fetches under <all_urls> host permissions. A malicious page can abuse this to make the extension request arbitrary internal/network URLs (SSRF-style) and then read the resulting data URI from the injected hover card DOM. Consider restricting prefetch to same-origin links (or disabling prefetch by default / gating behind explicit user action) and rejecting non-http(s) URLs.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Comment on lines +272 to +279
browser.runtime.sendMessage({ type: 'extract-thumbnail', url: anchor.href })
.then((response) => {
if (response?.dataUri) {
thumbnailCache.set(anchor.href, response);
if (activeCard === card) {
const thumbDiv = card.querySelector('.rhwp-thumb-loading');
if (thumbDiv) insertThumbnailImg(thumbDiv, response.dataUri);
}

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

loadThumbnail sends an 'extract-thumbnail' message for anchor.href without any origin/scheme constraints. Since the resulting data URI is rendered into the page DOM, this can be used to exfiltrate fetched content to the page if the extension is tricked into fetching a sensitive URL. Consider adding URL validation here (e.g., require http(s) and same-origin with the current document) before requesting extraction.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Comment on lines +5 to +28
browser.runtime.onMessage.addListener((message, sender) => {
const handler = messageHandlers[message?.type];
if (!handler) return undefined;

return Promise.resolve(handler(message, sender))
.catch((err) => ({ error: err.message || String(err) }));
});
}

const messageHandlers = {
'open-hwp': (message) => {
openViewer({ url: message.url, filename: message.filename });
return { ok: true };
},

'fetch-file': async (message) => {
const response = await fetch(message.url);
if (!response.ok) {
return { error: `HTTP ${response.status}: ${response.statusText}` };
}

const buffer = await response.arrayBuffer();
return { data: Array.from(new Uint8Array(buffer)) };
},

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

This message router trusts any sender and allows fetching arbitrary URLs via 'fetch-file' and 'extract-thumbnail' under <all_urls> host permissions. The repo already has a sender validation helper (rhwp-shared/security/sender-validator.js) used by the Safari build; consider applying similar sender checks here (e.g., only allow fetch-file from internal viewer pages, and strongly constrain/validate URLs for extract-thumbnail).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Comment thread rhwp-firefox/package.json Outdated
ivLis-Studio and others added 3 commits April 25, 2026 18:38
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@edwardkim

Copy link
Copy Markdown
Owner

@ivLis-Studio 님, Firefox 확장 기여 의지에 진심으로 감사드립니다.

현재 상황

본 PR 의 변경 영역인 rhwp-firefox/ 디렉토리는 이미 devel 브랜치에 v0.2.1 까지 발전된 상태로 존재하며, 현재 AMO (Mozilla Add-ons) 제출 검토 중입니다.

PR 의 base 가 main 이라 main 에는 보이지 않지만 (devel → main 릴리즈는 별도 시점), devel 에는 다음이 이미 들어가 있습니다:

  • rhwp-firefox/manifest.json (gecko id, data_collection_permissions, _locales 다국어)
  • rhwp-firefox/_locales/ (한/영 다국어 메시지)
  • rhwp-firefox/PRIVACY.md (개인정보 처리방침 — AMO 필수)
  • rhwp-firefox/sw/* (service worker 모듈)
  • rhwp-firefox/dev-tools-inject.js

결정

본 PR 을 close 처리하겠습니다. 사유:

  1. 우리 측 v0.2.1 가 AMO 제출 검토 중인 단계라 같은 영역에 외부 코드 머지 시 제출 흐름 파편화 위험
  2. PR 의 16 파일 모두 우리 기존 파일과 동일 경로 — 코드 자체 충돌
  3. 우리 기존 manifest 가 가진 gecko id, data_collection_permissions, 다국어 _locales 등이 본 PR 에서는 누락 (AMO 제출 전제 조건)

한 가지 안내 — 우리 측 책임

PR 이 main 으로 제출된 점은 우리 측 안내가 부족한 면도 있습니다:

  • GitHub 저장소 default branch 가 main
  • README 에 base 브랜치 안내가 없음 (CONTRIBUTING.md 에만 있음)
  • 다음 외부 기여자도 같은 혼란을 겪을 가능성

이 부분은 우리 측에서 README 에 base=devel 안내 추가 로 개선 후속 처리하겠습니다.

향후 기여 환영

Firefox 확장 영역에 다음과 같은 후속 기여 환영합니다:

  • 현재 rhwp-firefox/ 의 manifest 워닝 해결 (예: strict_min_version 상향)
  • 다국어 추가 (영어/일본어 등)
  • UX 개선 (옵션 페이지, 단축키)
  • 보안 강화 (innerHTML 사용처 sanitize)

기여 시 devel 브랜치에서 분기 + 본인 fork 의 feature 브랜치 push + base=devel 로 PR 부탁드립니다.

다시 한 번 기여 의지에 감사드립니다.

@edwardkim edwardkim closed this Apr 25, 2026
edwardkim added a commit that referenced this pull request Apr 25, 2026
PR #330 (@ivLis-Studio Add Firefox Extension) 정중한 close 처리:
- 우리 측 rhwp-firefox/ v0.2.1 가 이미 devel 에 존재 + AMO 제출 검토 중
- 16 파일 모두 동일 경로 충돌 + AMO 전제 조건 (gecko id, _locales, PRIVACY.md) 누락

후속 개선:
- README.md / README_EN.md 의 Contributing 섹션 강화
  - PR base 는 devel (main 아님) 명시
  - 이슈/PR 사전 확인 안내
  - 이슈 close 는 메인테이너 안내
- AMO 워닝 feedback 문서 commit (별도 task 후보)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ivLis-Studio

Copy link
Copy Markdown
Author

아하 그랬군요.
확인했습니다!

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.

3 participants