Skip to content

fix(rhwp-chrome): 썸네일 로딩 스피너 정리 + options CSP 호환#167

Closed
postmelee wants to merge 2 commits intoedwardkim:develfrom
postmelee:fix/chrome-clean
Closed

fix(rhwp-chrome): 썸네일 로딩 스피너 정리 + options CSP 호환#167
postmelee wants to merge 2 commits intoedwardkim:develfrom
postmelee:fix/chrome-clean

Conversation

@postmelee
Copy link
Copy Markdown
Contributor

@postmelee postmelee commented Apr 16, 2026

변경 요약

Chrome 확장에서 두 가지 사용자 체감 이슈를 수정했습니다.

  1. 썸네일 로딩 완료 후에도 모래시계(⏳)가 남아 보이던 문제를 수정했습니다.
    • rhwp-chrome/content-script.js
    • insertThumbnailImg()에서 이미지 삽입 전에 thumbDiv.textContent = ''로 로딩 플레이스홀더를 제거
  2. 옵션 페이지가 비어 보이던 CSP 문제를 수정했습니다.
    • rhwp-chrome/options.html 인라인 스크립트를 제거하고 options.js로 분리
    • rhwp-chrome/build.mjs에서 options.jsdist/로 복사하도록 반영

변경 파일:

  • rhwp-chrome/content-script.js
  • rhwp-chrome/options.html
  • rhwp-chrome/options.js (신규)
  • rhwp-chrome/build.mjs

관련 이슈

closes #86
closes #166

테스트

  • cargo test 통과
  • cargo clippy -- -D warnings 통과
  • 관련 샘플 파일로 SVG 내보내기 확인 (N/A: rhwp-chrome 변경 범위 외)
  • 웹(WASM) 렌더링 확인 (해당하는 경우) (N/A: rhwp-chrome 변경 범위 외)
  • cd rhwp-chrome && npm run build 실행
  • Chrome 개발자 모드에서 rhwp-chrome/dist 로드 후 옵션 페이지/썸네일 동작 수동 확인

스크린샷

  • 옵션 페이지: 인라인 스크립트 차단으로 텍스트가 비던 상태에서 정상 텍스트 표시 상태로 개선
  • 썸네일 호버: 로딩 완료 후 스피너 제거되고 썸네일만 표시

postmelee and others added 2 commits April 16, 2026 22:40
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 16, 2026 16:45
@postmelee postmelee closed this Apr 16, 2026
@postmelee postmelee deleted the fix/chrome-clean branch April 16, 2026 16:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Chrome 확장 프로그램의 사용자 체감 문제(호버 썸네일 로딩 표시, 옵션 페이지 CSP) 2가지를 해결해 확장 UI/옵션 동작을 정상화합니다.

Changes:

  • 호버 썸네일 이미지 삽입 시 로딩 플레이스홀더(⏳)를 제거하도록 처리
  • 옵션 페이지 인라인 스크립트를 외부 파일(options.js)로 분리해 CSP 호환
  • 빌드 스크립트에서 options.jsdist/로 복사하도록 반영

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
rhwp-chrome/content-script.js 썸네일 이미지 삽입 시 로딩 플레이스홀더 제거로 UI 잔상 해결
rhwp-chrome/options.html 인라인 스크립트 제거 및 외부 스크립트 로드로 CSP 대응
rhwp-chrome/options.js 옵션 i18n/설정 로드·저장 로직을 외부 스크립트로 분리
rhwp-chrome/build.mjs 배포 산출물에 options.js 포함되도록 복사 단계 추가

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

Comment thread rhwp-chrome/options.js
Comment on lines +1 to +34
// i18n 적용
document.getElementById('title').textContent = chrome.i18n.getMessage('optionsTitle');
document.getElementById('labelAutoOpen').textContent = chrome.i18n.getMessage('optionsAutoOpen');
document.getElementById('labelShowBadges').textContent = chrome.i18n.getMessage('optionsShowBadges');
document.getElementById('labelHoverPreview').textContent = chrome.i18n.getMessage('optionsHoverPreview');
document.getElementById('saved').textContent = chrome.i18n.getMessage('optionsSaved');
document.getElementById('privacy').textContent = chrome.i18n.getMessage('optionsPrivacy');

const inputs = ['autoOpen', 'showBadges', 'hoverPreview'];

// 설정 로드
chrome.storage.sync.get(
{ autoOpen: true, showBadges: true, hoverPreview: true },
(settings) => {
for (const id of inputs) {
document.getElementById(id).checked = settings[id];
}
}
);

// 설정 저장
for (const id of inputs) {
document.getElementById(id).addEventListener('change', () => {
const settings = {};
for (const id2 of inputs) {
settings[id2] = document.getElementById(id2).checked;
}
chrome.storage.sync.set(settings, () => {
const saved = document.getElementById('saved');
saved.classList.add('show');
setTimeout(() => saved.classList.remove('show'), 1500);
});
});
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

options.js가 전역 스코프에서 실행되어 inputs 등이 options 페이지 전역에 노출됩니다. 이 레포의 다른 non-module 스크립트(content-script.js, dev-tools-inject.js)는 IIFE + 'use strict'로 감싸 전역 오염을 방지하고 있어 동일 패턴을 적용하는 게 안전합니다.

Suggested change
// i18n 적용
document.getElementById('title').textContent = chrome.i18n.getMessage('optionsTitle');
document.getElementById('labelAutoOpen').textContent = chrome.i18n.getMessage('optionsAutoOpen');
document.getElementById('labelShowBadges').textContent = chrome.i18n.getMessage('optionsShowBadges');
document.getElementById('labelHoverPreview').textContent = chrome.i18n.getMessage('optionsHoverPreview');
document.getElementById('saved').textContent = chrome.i18n.getMessage('optionsSaved');
document.getElementById('privacy').textContent = chrome.i18n.getMessage('optionsPrivacy');
const inputs = ['autoOpen', 'showBadges', 'hoverPreview'];
// 설정 로드
chrome.storage.sync.get(
{ autoOpen: true, showBadges: true, hoverPreview: true },
(settings) => {
for (const id of inputs) {
document.getElementById(id).checked = settings[id];
}
}
);
// 설정 저장
for (const id of inputs) {
document.getElementById(id).addEventListener('change', () => {
const settings = {};
for (const id2 of inputs) {
settings[id2] = document.getElementById(id2).checked;
}
chrome.storage.sync.set(settings, () => {
const saved = document.getElementById('saved');
saved.classList.add('show');
setTimeout(() => saved.classList.remove('show'), 1500);
});
});
}
(function () {
'use strict';
// i18n 적용
document.getElementById('title').textContent = chrome.i18n.getMessage('optionsTitle');
document.getElementById('labelAutoOpen').textContent = chrome.i18n.getMessage('optionsAutoOpen');
document.getElementById('labelShowBadges').textContent = chrome.i18n.getMessage('optionsShowBadges');
document.getElementById('labelHoverPreview').textContent = chrome.i18n.getMessage('optionsHoverPreview');
document.getElementById('saved').textContent = chrome.i18n.getMessage('optionsSaved');
document.getElementById('privacy').textContent = chrome.i18n.getMessage('optionsPrivacy');
const inputs = ['autoOpen', 'showBadges', 'hoverPreview'];
// 설정 로드
chrome.storage.sync.get(
{ autoOpen: true, showBadges: true, hoverPreview: true },
(settings) => {
for (const id of inputs) {
document.getElementById(id).checked = settings[id];
}
}
);
// 설정 저장
for (const id of inputs) {
document.getElementById(id).addEventListener('change', () => {
const settings = {};
for (const id2 of inputs) {
settings[id2] = document.getElementById(id2).checked;
}
chrome.storage.sync.set(settings, () => {
const saved = document.getElementById('saved');
saved.classList.add('show');
setTimeout(() => saved.classList.remove('show'), 1500);
});
});
}
})();

Copilot uses AI. Check for mistakes.
@postmelee postmelee restored the fix/chrome-clean branch April 16, 2026 16:50
@postmelee postmelee reopened this Apr 16, 2026
postmelee added a commit to postmelee/rhwp that referenced this pull request Apr 16, 2026
Copilot 리뷰 (PR edwardkim#167) 반영 — 다른 non-module 스크립트
(content-script.js, dev-tools-inject.js)와 동일하게 IIFE +
'use strict' 패턴으로 감싸 전역 스코프 오염 방지.
@postmelee
Copy link
Copy Markdown
Contributor Author

본 PR은 #168로 대체되어 close합니다. (PR 타임라인 정리 + Copilot 리뷰 반영 커밋 포함)

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.

2 participants