Skip to content

Feature: support ImageAddress in viewport geometry and navigation APIs #3954

Description

@optimistic9527

What problem does this solve?

I am building an image-aware annotation/redaction UI on SuperDoc v2. The Document API can enumerate exact image occurrences through doc.images.list(), returning an sdImageId and stable ImageAddress, but the public viewport API cannot resolve or navigate to that image.

In the published superdoc@2.10.0 types:

interface ImageAddress {
  kind: 'inline'
  nodeType: 'image'
  nodeId: string
  placement: 'inline' | 'floating'
}

type ViewportGetRectTarget =
  | SelectionTarget
  | TextAddress
  | TextTarget
  | ViewportEntityAddress

interface ScrollIntoViewInput {
  target: TextAddress | TextTarget | EntityAddress
}

As a result, neither of these supported workflows is currently possible:

const image = (await doc.images.list()).items[0]

superdoc.ui.viewport.getRect({ target: image.address })
await superdoc.ui.viewport.scrollIntoView({ target: image.address })

This blocks product features that need to:

  • project OCR or redaction rectangles over a specific rendered image occurrence;
  • distinguish duplicate uses of the same image asset;
  • scroll to an inline or floating image selected in an external findings list;
  • recompute image overlays after zoom, pagination, virtualization, or layout changes.

The v1 integration can approximate this by combining ProseMirror positions, renderer-owned DOM attributes, OOXML relationship IDs, and getBoundingClientRect(). Those are not public v2 surfaces. The v2 migration guide also notes that an image is a structural block with no paragraph-index entry, so wrapping its ID in a TextAddress does not provide a supported workaround.

Proposed solution

Please make image addresses first-class viewport targets, either directly or through a dedicated public image viewport address:

type ViewportGetRectTarget =
  | SelectionTarget
  | TextAddress
  | TextTarget
  | ViewportEntityAddress
  | ImageAddress

interface ScrollIntoViewInput {
  target: TextAddress | TextTarget | EntityAddress | ImageAddress
}

It would also be useful for point hit-testing to expose the same stable occurrence identity:

superdoc.ui.viewport.entityAt({ x, y })
// [{ type: 'image', id: sdImageId, nodeId, placement }]

Suggested behavior and acceptance criteria:

  • getRect({ target: image.address }) returns the painted visible bounds for inline and floating images.
  • Geometry reflects crop, rotation, scaling, and the actual rendered placement.
  • Duplicate references to the same media asset remain distinguishable by occurrence.
  • scrollIntoView() mounts/reveals the correct page in a virtualized document.
  • Images in supported stories, including headers, footers, and text boxes, are addressable or return a documented scoped failure.
  • viewport.observe() invalidates consumers when the image geometry may have changed.
  • The contract is supported without querying renderer-owned DOM or importing internal layout packages.

Alternatives considered

  1. Query rendered <img> nodes and call getBoundingClientRect(). This depends on private renderer DOM, does not provide a supported mapping to sdImageId/ImageAddress, and is fragile under virtualization and re-painting.
  2. Navigate to the image's anchor paragraph. This is not exact for floating images and does not yield the image's painted rectangle.
  3. Parse OOXML independently and match by relationship ID, asset hash, or document order. That can identify an occurrence but still cannot obtain supported viewport geometry.
  4. Continue using v1 internals. This works as a compatibility bridge but prevents a safe v2 migration.

Additional context

Verified against the published public types for:

  • superdoc@2.10.0 (latest)
  • superdoc@2.11.0-next.13 (next)

The relevant migration documentation is:

A minimal reproduction document only needs one inline image and one floating image. doc.images.list() supplies both addresses; the missing step is resolving those addresses through the public viewport geometry and navigation surfaces.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions