Skip to content

feat: add HWPX fragment paste support#950

Closed
dragonnite1221-lgtm wants to merge 2 commits into
edwardkim:develfrom
dragonnite1221-lgtm:public/hwpx-fragment-paste
Closed

feat: add HWPX fragment paste support#950
dragonnite1221-lgtm wants to merge 2 commits into
edwardkim:develfrom
dragonnite1221-lgtm:public/hwpx-fragment-paste

Conversation

@dragonnite1221-lgtm

Copy link
Copy Markdown
Contributor

Adds HWPX fragment paste support, WASM bridge APIs, rhwp-studio insertion UI, bundled example yangsik fragments, and regression tests.

This is a follow-up to closed PR #880 and addresses the review feedback there.

Architecture note

This PR intentionally keeps two paste boundaries because they serve different safety contracts.

  • pasteHwpxFragmentRaw / fragment_paste.rs is the raw XML primitive. It performs byte-preserving section/header edits and owns HWPX ID remapping for raw snippets.
  • pasteHwpxFragmentInDocument / fragment_paste_in_document.rs is the editor-facing bridge. It reuses the raw XML primitive, then reparses the updated section back into DocumentCore so rendering and later edit commands stay in sync.
  • cross_document_migrate.rs is the IR migration primitive for future structured cross-document copy/paste. It stays separate from the raw HWPX fragment path because it operates on Document/DocInfo IR, not byte-preserved HWPX XML. The convergence point is the command/API layer: raw HWPX fragments use the byte-preserving path now; structured IR copy/paste can use the migration primitive when that workflow is exposed.

Review follow-up

  • Rebased onto current origin/devel.
  • Removed the as any call by using the generated WASM binding type for pasteHwpxFragmentInDocument.
  • Removed local-machine yangsik smoke tests and kept self-contained bridge tests using saved/04-blank_hwpx_empty.hwpx.
  • Aligned blank HWPX seed comments with saved/04-blank_hwpx_empty.hwpx.
  • Removed the unused build_occupied_sets helper.
  • Added bundled example fragments under rhwp-studio/public/yangsik-fragments/ so the dialog is non-empty and end-to-end testable by maintainers.
  • Gated the 양식 부품 command to HWPX documents; HWP5 documents do not expose this unsupported XML-fragment operation.
  • Hardened the fragment catalog endpoint against traversal, double-encoded path traversal, symlinks, writable catalog files, TOCTOU reads, and oversized manifest/fragment files.

Validation

  • cargo test --test fragment_paste_integration --test fragment_paste_in_document
  • cargo test fragment_paste
  • cd rhwp-studio && npm run build
  • gitleaks detect --source . --log-opts origin/devel..HEAD --redact --no-banner --verbose
  • Dev endpoint smoke check:
    • manifest returns bundled entries
    • basic-two-cell-table.xml returns 200
    • encoded traversal probe returns 404
  • Codex second-review gate: clean via gemini-oauth, risk=medium

@edwardkim edwardkim self-requested a review May 17, 2026 08:07
@edwardkim edwardkim added the enhancement New feature or request label May 17, 2026
@edwardkim

Copy link
Copy Markdown
Owner

PR 검토가 늦는 점 양해의 말씀드립니다.
현재 보내주신 PR 에서 메뉴의 용어 "양식 부품" 은 너무 기계적입니다. 또한 프론트-엔드쪽 기능을 위해 의존성을 추가하는 것도 현재 rhwp 의 거버넌스에 반하는 패턴입니다. 좀더 살펴보도록 하겠습니다.

@dragonnite1221-lgtm dragonnite1221-lgtm force-pushed the public/hwpx-fragment-paste branch from 0d25344 to bebda1f Compare May 19, 2026 05:16
@edwardkim

Copy link
Copy Markdown
Owner

검토와 메인테이너 hands-on 테스트를 진행했습니다. 코드 측 PR #880 잔존 항목은 대부분 해소된 것으로 보이나, 실제 동작에서 두 가지 결함이 발견되어 본 PR 은 close 합니다.

메인테이너 테스트 결과

테스트 경로:

  1. samples/hwpx/blank_hwpx.hwpx 파일 열기
  2. 상단 메뉴 → 입력 → 서식 조각 → 다이얼로그 표시 확인
  3. 제목박스 탭 → "문서 제목 박스" 항목 클릭 → 자동 삽입은 동작

발견된 결함

1. 다이얼로그 종료 UX 결함

"문서 제목 박스" 삽입 후 확인 버튼을 눌러도 다이얼로그가 닫히지 않습니다. 취소 버튼으로만 닫을 수 있습니다.

코드 위치: rhwp-studio/src/ui/yangsik-parts-dialog.ts:101

protected onConfirm(): boolean {
  return false;
}

ModalDialog base 의 contract (rhwp-studio/src/ui/dialog.ts:127) 는 "false 반환 시 대화상자 유지" 이므로, 위 구현은 명시적으로 확인 버튼을 무시합니다. 카드 클릭으로 즉시 삽입하는 패턴이라 확인 버튼이 의미가 없는 것으로 의도된 것 같으나, 사용자에게는 "확인 버튼이 보이는데 동작하지 않는다" 로 인지되어 자연스러운 사용 시나리오가 아닙니다.

해결 방향 후보:

  • (a) 확인 버튼을 다이얼로그에서 숨김 (base class 에 옵션 추가 필요)
  • (b) 확인 = "닫기" 동작으로 처리 (true 반환)
  • (c) 단일 액션 다이얼로그 (popover, side panel 등) 로 UI 재설계

2. 빈 HWPX 문서 (paragraph 1 개) 에서 삽입 실패

PR 이 fixture 로 추가한 saved/04-blank_hwpx_empty.hwpx 또는 다른 빈 HWPX 문서에서 시도 시 다음 오류:

paste failed: malformed fragment: after_para_idx 1 out of range
(section has 1 top-level paragraphs)

원인 추정: frontend 의 pos.paragraphIndex 가 1 로 전달되는데 (커서 본문 첫 paragraph), Rust 측 paste_paragraphs_into_sectionafter_para_idx 검증 (fragment_paste.rs:416) 은 0-based 유효 인덱스를 기대 → off-by-one 또는 semantic 불일치.

PR 처리

위 두 결함은 사용자가 자연스럽게 사용할 수 있는 시나리오가 아니라 판단되어 본 PR 은 close 합니다.

핵심 기능 자체 (raw HWPX fragment paste primitive, WASM bridge, HWPX 전용 gating) 는 PR #880 검토 시 평가한 대로 잘 설계되어 있고, PR #880 잔존 항목들 (예시 fragment 추가, HWP5 비호환 guard, 비공개 smoke 테스트 제거, 카탈로그 보안 강화) 도 성실히 반영해 주셔서 감사합니다.

재제출 시 권고 사항

위 1, 2 외에도 본 검토에서 다음 사항이 확인되었습니다. 재제출 시 함께 반영 부탁드립니다.

필수

  • 빈 HWPX 문서를 포함한 end-to-end 동작 테스트 (메인테이너 hands-on 게이트)
  • 확인 버튼 UX 재설계 — 사용자가 다이얼로그를 자연스럽게 닫을 수 있어야 함
  • cross_document_migrate.rs (1011 줄) 별도 PR 분리 — 본 PR 의 실제 paste 기능은 raw XML byte-preserving path 만 사용. future structured cross-document copy/paste workflow 가 노출될 때 별도 PR 로 제출 권장. v0.x 단계의 작은 단위 회전 정책에 정합.
  • 비공개 task 참조 주석 제거 — 코드 주석에 task_local_yangsik_paste_* 류의 비공개 task ID 가 잔존합니다 (RCA 일자 포함). 외부 공개 PR 에는 부적절합니다. 본 PR 번호 또는 이슈 번호로 대체 또는 일반 설명으로 정리 부탁드립니다.

권고

  • yangsik 명명 일관화 — UI 라벨은 "서식 조각" 으로 변경하셨으나 디렉토리/클래스/함수/명령 ID 는 yangsik-* 음역 그대로입니다 (public/yangsik-fragments/, YangsikPartsDialog, fetchYangsikFragment*, insert:yangsik-parts). 옵션 A (영어 — form-snippet / fragment) 또는 옵션 B (일관 음역 — seosik-jogak) 중 선택해 일관 정리 권장. UI/코드 표기 일치가 유지보수에 도움됩니다.

기여 감사합니다. 위 사항이 반영된 새 PR 을 다시 보내주시면 재검토 진행하겠습니다.

@edwardkim edwardkim closed this May 21, 2026
edwardkim pushed a commit that referenced this pull request May 21, 2026
HWPX fragment paste support — 메인테이너 hands-on 테스트에서 동작
결함 2건 발견으로 close. 컨트리뷰터에게 재제출 권고.

발견 결함:
- B1: 빈 HWPX 문서에서 after_para_idx 1 out of range
- B2: 확인 버튼 무동작 — onConfirm() 항상 false 반환

기타 수정요청 항목 (재제출 시 권고):
- M1: 비공개 task 참조 주석 (task_local_yangsik_paste_*) 제거
- M2: cross_document_migrate.rs (미사용 1011줄) 별도 PR 분리
- R1: yangsik 명명 UI ↔ 코드 불일치 해소

PR #880 잔존 6 항목 중 코드 측은 대부분 성실 반영 (예시 fragment,
HWP5 비호환 guard, 카탈로그 보안 강화). 핵심 기능 설계도 양호.
그러나 end-to-end UX 게이트 미통과로 close.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 21, 2026
- PR #950 (HWPX fragment paste support, dragonnite1221-lgtm) — 메인테이너
  hands-on 테스트에서 B1 빈 HWPX paste 실패 + B2 확인 버튼 무동작
  발견으로 close. 재제출 시 권고 사항 (B1+B2+M1+M2+R1) 정리.
- PR #1039 (HWPX slash/backSlash 형태 enum 파싱 분리, planet6897, closes
  #1038) — merge 수용. "정량 게이트 충족 시 시각 판정 면제" 첫 권위
  사례 (결정적 측정 3→0 + 회귀 가드 단위 테스트 4건 + parser-only
  scope 3 조건 동시 만족).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants