Skip to content

Document의 동일 블록 내 offset 선택과 범위 확장을 반영한다 #723

Closed

Description

@developer-1px

Goal Anchor

  • Outcome: Document의 같은 블록 안에서도 selection.set이 요청한 offset과 범위 확장을 반영하여 직접 API 호출과 Document text control이 같은 선택 상태를 사용한다.
  • Done: 초기 offset 0에서 2로 이동, 같은 블록 내 양방향 extend와 collapse, 경계 보정이 공개 API와 실제 Document 입력 경로에서 확인된다. 선택만으로 document·기존 Undo/Redo 기록을 바꾸지 않고, 이어지는 편집의 Undo가 변경 전 offset/범위를 복원한다. 블록 단위 toggle·Copy의 기존 의미도 유지한다.
  • Don’t: Core API, 선택 shape, 명령 이름, 블록 단위 Copy/Cut/Paste 의미, 다른 editor의 선택 정책, History owner를 바꾸지 않는다. 새 editor/command registry나 Host-local 우회 구현을 만들지 않는다.

앞서 PR #722에서 기록한 동일 블록 offset 공백에 대해 사용자가 “계속해”로 후속 진행을 요청했다. #721/#722의 공통 적합성 설계는 유지하고 이 재현 가능한 구현 결함은 별도 변경으로 해결한다. Merge는 포함하지 않는다.

재현과 원인

const editor = createDocumentEditor({ blocks: [{ id: "a", text: "Alpha" }] });
editor.dispatch({ type: "selection.set", blockId: "a", offset: 2 });
// 현재: 성공이지만 anchor/focus offset은 0
// 기대: anchor/focus offset은 2

document.ts는 selectRangePoint에 block ID만 비교하는 함수를 전달한다. 이 함수가 RangeSelection의 point 동등성에도 쓰여서 같은 블록의 offset 변경이 이전 상태와 같다고 판정된다. 블록 toggle의 대상 동등성과 커서/range endpoint의 동등성을 구별해야 한다.

정본 owner는 json-document-editing/src/document.ts와 기존 Selection family다. Document Demo는 DocumentTextControl의 onCaretRange에서 같은 공개 selection.set을 호출하므로 Demo-local 계산으로 우회하지 않는다. 인접 Order/Tree/Sheet/Database의 같은 helper 사용도 비교해 수정 범위를 확인한다.

검증과 문서

  • Document editor 회귀: point 이동·extend·collapse·clamp, 동일 block toggle, 전체 블록 Copy, publication, 선택과 History의 독립성 및 복원
  • 기존 Editing·Selection·React 관련 테스트·타입 검사·빌드
  • 기존 Document Usage를 기존 Chrome 연결로 확인하고 해당 owner 문서·API reference·source 등록을 검증

#719 / PR #720의 세션 보완은 현재 main에 반영됐다. 그 변경을 새로 구현하지 않는다.

Activity

  1. self-assigned this
    on Sep 7, 2026
  2. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    Goal Anchor

    • Outcome: Document의 같은 블록 안에서도 selection.set이 요청한 offset과 범위 확장을 반영하여 직접 API 호출과 Document text control이 같은 선택 상태를 사용한다.
    • Done: 초기 offset 0에서 2로 이동, 같은 블록 내 양방향 extend와 collapse, 경계 보정이 공개 API와 실제 Document 입력 경로에서 확인된다. 선택만으로 document·기존 Undo/Redo 기록을 바꾸지 않고, 이어지는 편집의 Undo가 변경 전 offset/범위를 복원한다. 블록 단위 toggle·Copy의 기존 의미도 유지한다.
    • Don’t: Core API, 선택 shape, 명령 이름, 블록 단위 Copy/Cut/Paste 의미, 다른 editor의 선택 정책, History owner를 바꾸지 않는다. 새 editor/command registry나 Host-local 우회 구현을 만들지 않는다.

    작업 계획

    1. 동일 블록 replace/extend/collapse와 History·블록 toggle/Copy의 회귀를 먼저 실행해 기존 실패를 확인한다.
    2. Document의 point 비교에서 블록 토글의 target 동등성과 offset을 포함하는 endpoint 동등성을 구별한다. 기존 Selection family를 소비하며 공개 shape를 바꾸지 않는다.
    3. 기존 DocumentTextControl→selection.set 경로를 연결해 검증하고 owner 문서·Usage/source 등록과 실제 Chrome 경로를 확인한다.
    4. 관련 테스트·타입 검사·빌드와 PR 검증을 마친다.

    인접 소비자를 확인했다. Order/Tree의 point는 각각 item ID/node ID이고 Sheet/Database는 두 축의 ID를 모두 비교한다. offset을 가진 point 일부만 비교하는 누락은 Document에 있다. 최신 main c051f380에서 issue branch를 만들고 lockfile로 의존성을 재설치했다. PR #722는 별도 브랜치에 유지한다.

  3. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    실제 입력 경로에서 확인한 추가 원인

    Document의 block ID 비교를 고친 뒤 동일 블록 이동·양방향 확장·복원 11개 테스트가 통과했다. 이어서 실제 DocumentTextControl과 editor를 연결하니 네이티브 범위 [2, 4]를 snapshot focus 4로 다시 그릴 때 [4, 4]로 접는 회귀를 재현했다. 현재 control은 backward selection도 정렬된 start/end로 전달해 anchor/focus를 뒤집는다.

    이는 이 이슈 Done의 실제 Document 입력 경로에서 같은 offset/range를 유지하는 조건을 막는 같은 흐름의 원인이다. Web 정본 input.ts에 textSelectionFromControl을 추가해 기존 SelectionRange<number>로 네이티브 방향을 해석한다. React는 이 API를 소비하고 native focus가 snapshot offset과 같으면 이미 선택된 범위를 보존한다. 다른 offset을 명시하면 기존 cursor 복원 API를 실행한다. Core, editor shape, 블록 toggle/Copy 및 다른 editor 정책은 유지한다.

    새 Web 공개 함수는 기존 Document Usage의 React binding에서 실행되며 owner README/API reference와 기존 source registry에 연결한다. 별도 Host-local translator나 새 selection model은 만들지 않는다. 기존 Chrome 제어는 생성한 탭을 후속 호출에서 찾을 수 없어 유지하지 못했고, 사전 안내 후 로그인 불필요한 로컬 데모를 Playwright의 별도 Chrome 테스트 프로필로 검사 중이다.

  4. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    구현 및 검증 완료

    원인의 연결을 기존 owner에서 닫았다.

    • Editing: 같은 블록의 replace/extend는 offset까지 비교하며 블록 toggle은 ID 기준을 유지한다.
    • Web: 네이티브 selectionDirection을 기존 SelectionRange의 anchor/focus로 번역한다. 새 공개 함수 textSelectionFromControl은 owner 문서/API reference와 기존 Document Usage/source 등록에 연결했다.
    • React: native focus가 model offset과 같을 때 범위를 커서로 접지 않는다. 방향을 보존한 offset을 기존 callback에 전달한다.
    • Document Host: textarea의 네이티브 입력을 가로채던 중복 keyboard.text 설정을 제거했다. 구조 탐색·History binding은 계속 기존 API를 사용한다.

    실패 재현: 기존 Document 구현에서 동일 블록 offset 및 History 복원 2개 회귀 실패. Document 수정 후 실제 React/editor 연결에서 [2,4]가 [4,4]로 접히는 실패도 재현했다. 각각 owner 수정 후 통과했다.

    검증:

    • 관련 6개 package: 57 files / 509 tests 통과
    • Editing·React·Web 테스트 포함 TypeScript 검사 및 workspace build 통과
    • Site source discovery 관련 2 files / 17 tests 통과
    • Chrome Document 시나리오 3개, React Connector·Clipboard 소비자 시나리오 3개 및 각 서버 setup 통과
    • docs:evaluate와 생성된 API reference 검사, site 전체 guard·TypeScript 검사 통과

    Core API·editor selection shape·블록 Copy/Cut/Paste 정책은 유지했다. offset 하나로 과거 네이티브 DOM 범위 전체를 복원한다는 보장은 추가하지 않았다. editor의 기록된 offset/range는 Undo로 복원하며 native control의 range와 외부 cursor 복원을 구별해 문서화했다. 다른 editor의 point 비교에는 같은 누락이 없었다.

  5. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    PR: #724

    상태: pr-open. 브랜치 issue-723-document-offset, commit bfa11fb7.

    원격 PR 본문·#723 closing 연결·16개 변경 경로·HEAD가 로컬 검증 대상과 일치함을 읽어 확인했다. 기존 문제를 수정한 구현·문서·회귀 및 브라우저 검증이 Goal Anchor의 Done을 충족하며, Core/selection shape/블록 편집 정책의 불변 조건을 유지한다. 프로젝트 연결은 없다.

    show-me: verified. 원격 PR과 동일 HEAD의 worktree가 제공하는 실제 Document 화면에서 커서 이동·정/역방향 Shift 선택을 제어하고, native [1,2,backward]와 editor intent의 focus 1, Undo 비활성, page error 없음까지 확인했다. 검증한 화면은 사용자 확인용으로 열어 두었다. 기존 Chrome 제어 제한 때문에 사전 안내한 별도 테스트 프로필을 사용했다.

    관련 package 509개 테스트, site source discovery 17개 테스트, Chrome 소비자 시나리오 6개, 빌드·타입·문서 검증 통과. CI는 진행 중이다. offset만으로 과거 native range 전체를 복원하는 보장은 추가하지 않았으며 해당 경계는 owner 문서에 명시했다.

  6. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    리뷰 보완 및 통합 검증 완료

    최종 검토 대상: 18f290ccda05513d4e78e7bd917dd46d4f3056ea. #722를 포함한 main을 통합했고 두 README의 계약을 모두 보존했다. offset 미해결 관찰은 수정 후 Editing·Web·React·실제 Document 회귀 증거로 연결했으며, Web의 선택 end·direction 생략 규칙을 명확히 했다. 추가 runtime 변경은 없다.

    통합 후 검증:

    • 관련 6개 package: 61 files / 556 tests 통과
    • Site source discovery: 2 files / 17 tests 통과
    • Chrome: Document 3개 + React Connector/Clipboard 소비자 3개 시나리오 통과(각 실행 setup도 통과)
    • Workspace build, site 전체 guard·TypeScript, docs:evaluate, API reference 검사(29개 package / 1033 exports), diff 검사 통과

    기존 Document 선택/복원과 React range collapse 실패는 구현 전에 재현한 회귀이며 이번 통합 후에도 해당 테스트가 통과한다. Core·selection shape·블록 toggle/Copy/Cut/Paste·History owner 불변 조건을 확인했다. offset 하나로 과거 native range 전체를 복원하거나 모든 profile을 Stable로 선언하는 계약은 추가하지 않았다.

    원격 PR 본문·HEAD·17개 변경 경로·#723 closing 연결이 검증한 로컬 상태와 일치한다. 머지를 막는 코드 결함이나 미해결 리뷰 의견은 없다. 현재 최신 커밋의 CI 실행을 확인 중이며 성공 후 사용자의 “리뷰 후 머지” 요청에 따라 머지한다.

  7. developer-1px commented on Sep 7, 2026

    @developer-1px
    OwnerAuthor

    리뷰 후 머지를 완료했다.

    통합 상태의 package 556개·site 17개 테스트, Chrome 제품 시나리오 6개, 빌드·타입·문서 검사 통과. 리뷰에서 확인한 문서 불일치는 수정 후 증거 및 Web 입력 fallback 설명으로 보완했다. 차단 결함과 미해결 리뷰는 없다.

    상태: landed-clean (이번 작업용 체크아웃). 작업용 체크아웃은 최신 main 929c27d8이며 검증한 #724 HEAD와 파일 트리가 일치한다. 머지된 두 작업의 로컬·원격 브랜치를 삭제했고 임시 검증 서버/브라우저도 종료했다. 원래 사용자 작업 폴더의 기존 변경은 보존했다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions