Skip to content

Implement live Selection and Window.find for nested webviews #405

Description

@wieslawsoltes

Reproduction

After #399, unchanged Code OSS 645f29cc3176500b4b5762ba887cf2a7f0ffdf2c reaches the Markdown iframe's active-document setup through its intentional 200 ms load fallback. With enableFindWidget, browser/pre/index.html then handles find by calling:

const selection = target.contentWindow.getSelection();
selection?.collapse(selection.anchorNode);
target.contentWindow.find(value, false, previous, true, false, false, false);

On WebScene 51f71381bda9015b64cf0566534e209f8bfa9986, contentWindow.find is undefined and getSelection() returns a new empty placeholder on each call, without anchor/range state. Chrome 153 exposes a stable live Selection and advances repeated find calls through the document.

Focused scope

  • Implement a realm-local live Selection identity for top-level and same-origin iframe windows.
  • Implement the Chromium-compatible Window.find subset used by Code OSS: forward/backward, case sensitivity, wrap, whole-word, repeated query, and selection reset through collapse(selection.anchorNode).
  • Search connected text content in document order and expose the active match through anchorNode, focusNode, offsets, rangeCount, getRangeAt, toString, collapse, and removeAllRanges/empty.
  • Reset selection/search cursors on document replacement, iframe detach, and realm destruction.

Security and collision boundary

Search and selection remain inside the calling realm's current document. Opaque/cross-origin iframe access stays fail-closed through the existing contentWindow boundary. This issue does not add cross-frame search, Shadow DOM traversal, editing commands, focus/input routing, accessibility publication, CSS behavior, File System behavior, or AppScene packaging.

Owned paths are the V8 DOM/window binding and realm/document lifecycle state, focused native browser-DOM tests, and one Chrome contract/profile. #400 owns File System mutation paths; #401 owns stylesheet CSSOM; the AppScene packaging stack owns no paths here.

Acceptance

  • Chrome-derived contract covers stable Selection identity, forward/backward, case, wrap, whole-word, repeat progression, miss behavior, and clear/collapse semantics.
  • Native unchanged Markdown find and find-stop calls match the oracle inside the replaced iframe document.
  • Cross-origin/opaque access remains unavailable; replacement and detach retire selection state and stale text-node handles.
  • A deterministic 100,000-text-node search is p95 <= 50 ms after indexing/search preparation; 100 search/replace/detach cycles retain <= 4 MiB heap and bounded RSS with no stale listeners or selection handles.
  • Exact-head Linux, macOS, portable V8, native-document, and NativeAOT gates pass.

Parent: #268
Epic: #264
Program: #227

Activity

  1. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Exact audited base: 51f71381bda9015b64cf0566534e209f8bfa9986.

    The unchanged Markdown prelude now advances through iframe navigation, document replacement, fallback activation, and ResizeObserver setup after #399. The first remaining product call that fails is the enabled find bridge: contentWindow.find is absent and getSelection() has no persistent range state.

    This child owns only realm-local Selection state, the Code OSS Window.find argument subset, reset on replacement/detach, and focused Chrome/native/performance/lifecycle evidence. It will touch V8 DOM/window bindings, realm lifecycle state, focused browser-DOM tests, and a dedicated contract/profile. It excludes #400 File System paths, #401 CSS paths, AppScene packaging, cross-origin capability expansion, cross-frame/Shadow DOM search, input routing, and accessibility publication.

  2. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Implementation is ready in #411 at exact head 76e9906b244536c5d38aa35aff6c0e11a8ebab59 on rebased main 54158141b50a48458fa788396f16b38adf1cc8e1. Chrome 153 and native both pass the 10/10 focused contract; the Code-shaped nested Markdown gate, 100-cycle teardown, bounded 100,000-text-node performance/memory gate, and adjacent iframe/navigation/resource filters pass. Awaiting only the direct exact-head PR checks.

  3. wieslawsoltes commented on Sep 18, 2026

    @wieslawsoltes
    CollaboratorAuthor

    Completed by #411, merged as d355d3fd021d792f97f5010aad5951ff7776b772.

    Final evidence: unchanged Code OSS Markdown reaches the nested frame find/find-stop bridge; Chrome 153 and native pass the focused contract 10/10; the exact Code-shaped nested-frame sequence passes; opaque/cross-origin access remains fail-closed; 100 create/navigate/find/remove cycles retain no listeners or native DOM nodes. The 100,000-text-node gate measured p95 17.67 ms (50 ms limit), flat V8 heap (1,390,808 bytes before/after), native nodes 7 -> 7, and bounded high-water RSS. Direct exact-head Linux, native-document, portable V8, and both NativeAOT checks passed; focused macOS product gates passed locally.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    vscode-oss/plannedPlanned for the AppScene/WebScene VS Code OSS integration

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions