Skip to content

Remove dormant html{zoom} and coordinate-compensation infrastructure #148

Description

@BorisTyshkevich

Goal

Delete the page-level CSS zoom bridge and every runtime/test path that compensates for it.

PR #147 set the page scale to native size:

--zoom: 1;

That made the complete zoom bridge a no-op, but the application still measures, publishes, propagates, divides by, and tests a zoom factor that can no longer differ from 1.

This issue removes that dead infrastructure and leaves every surface using native browser coordinates and containing-block sizing.

This is one atomic cleanup. Do not leave a mixed state where some popovers, drags, charts, or detached views still expect zoom-adjusted coordinates.


Scope

Remove all active implementation references to:

html { zoom: ... }
--zoom
--vp-zoom
zoomScale
viewportZoom
measureViewportZoom
applyViewportZoom
app.vpZoom
unzoomChartEvent
installChartZoomFix

Historical release notes may retain references to the removed behavior.


CSS

Remove page zoom

Delete:

html { zoom: var(--zoom); }

Delete these custom properties:

--zoom
--vp-zoom

Delete the fallback:

@supports not (zoom: 1) {
  ...
}

Remove comments that describe page-level CSS zoom, viewport-unit divergence, or zoom divisors.

Overlay sizing

The overlay is already a fixed viewport-sized containing block with its own padding:

.graph-overlay {
  position: fixed;
  inset: 0;
  padding: 24px;
}

Size its panel from the containing block:

.graph-overlay-panel {
  width: 100%;
  height: 100%;
}

Do not use viewport-unit division or a replacement JavaScript measurement.

Detached views

Use native full-height layout:

html,
body {
  height: 100%;
}

body.detached-tab {
  height: 100%;
}

body.detached-tab .graph-overlay-panel {
  width: 100%;
  height: 100%;
}

Keep the existing detached-tab border and border-radius overrides.

Do not copy sizing custom properties from the opener.


Delete viewport measurement

Delete:

src/core/zoom-support.js

Remove from src/ui/app.js:

viewportZoom import
app.measureViewportZoom
app.applyViewportZoom
app.vpZoom
the post-mount app.applyViewportZoom() call

Do not replace this with another probe or resize observer.

Fullscreen surfaces must size correctly from normal CSS layout.


Native-coordinate anchoring

Delete zoomScale

Remove zoomScale() from:

src/ui/dom.js

Remove every import and call.

Keep and simplify fixedAnchor

Popover anchoring is still shared behavior and must remain centralized.

Change:

fixedAnchor(rect, scale, opts)

to:

fixedAnchor(rect, opts)

Required behavior:

export function fixedAnchor(rect, opts = {}) {
  const gap = opts.gap != null ? opts.gap : 6;
  const min = opts.min != null ? opts.min : 8;
  const top = rect.bottom + gap;

  return opts.viewportW != null
    ? {
        top,
        right: Math.max(min, opts.viewportW - rect.right),
      }
    : {
        top,
        left: Math.max(min, rect.left),
      };
}

Update all callers:

src/ui/app.js
src/ui/file-menu.js
src/ui/combobox.js
src/ui/combo-footer.js

Popover widths

Replace:

rect.width / scale

with:

rect.width

This applies to:

  • combobox list width;
  • combobox footer width;
  • any other anchored fixed-position element.

Drag and resize cleanup

All pointer events and layout dimensions now use native CSS pixels.

Remove every scale argument, scale callback, and division.

Splitters

Change:

dragValue(axis, event, rect, scale)

to:

dragValue(axis, event, rect)

Native behavior:

if (axis === 'col') {
  return clamp(event.clientX, 180, 420);
}

if (axis === 'drawer') {
  return clampDrawerWidth(rect.width - event.clientX, rect.width);
}

Keep percentage-based axes unchanged.

Remove ctx.scale from startDrag().

Update all callers in src/ui/app.js and src/ui/results.js.

Result-grid columns

Change:

colResizeWidth(startWidth, deltaX, scale)

to:

colResizeWidth(startWidth, deltaX)

Implementation:

return Math.max(MIN_COL, Math.round(startWidth + deltaX));

Remove the zoomScale() measurement from column-resize startup.

This applies to all shared grid consumers, including script-result grids.

Schema detail height

Replace:

(r.bottom - event.clientY) / scale
r.height / scale

with:

r.bottom - event.clientY
r.height

Remove the zoom measurement and zoom-specific comments.

Cell-detail drawer

Remove the scale callback passed to startDrag().

The drawer width calculation uses native clientX directly.


Chart.js cleanup

Delete from src/core/chart-data.js:

unzoomChartEvent

Delete from src/ui/chart-render.js:

zoomScale import
unzoomChartEvent import
installChartZoomFix

Instantiate Chart.js directly:

const chart = new app.Chart(
  canvas,
  chartJsConfig(...)
);

Keep the existing detached-document resize/update handling. It solves a cross-realm Chart.js sizing problem and is unrelated to CSS zoom.

Update comments so they describe only the cross-realm behavior.


Detached-view cleanup

In src/ui/detached-view.js:

  • stop reading --vp-zoom from the opener;
  • stop writing it into the child document;
  • retain theme and density mirroring;
  • retain copied stylesheet and favicon behavior;
  • retain tab/overlay fallback behavior.

Rename mirrorTheme() only when needed for clarity. A rename is not required.


Files

Expected modifications:

src/styles.css

src/ui/dom.js
src/ui/app.js
src/ui/file-menu.js
src/ui/combobox.js
src/ui/combo-footer.js
src/ui/chart-render.js
src/ui/grid-render.js
src/ui/results.js
src/ui/schema-detail.js
src/ui/detached-view.js
src/ui/splitters.js

src/core/chart-data.js

tests/unit/dom.test.js
tests/unit/app.test.js
tests/unit/chart-data.test.js
tests/unit/grid-render.test.js
tests/unit/splitters.test.js
tests/unit/schema-detail.test.js
tests/unit/detached-view.test.js

Delete:

src/core/zoom-support.js
tests/unit/zoom-support.test.js
tests/e2e/zoom-support.spec.js
tests/e2e/zoom.html

Update other tests discovered by the final repository search.

No new runtime dependency.


Test requirements

Repository-wide dead-code search

The implementation is incomplete when active source or active tests contain any of:

--zoom
--vp-zoom
zoomScale
viewportZoom
measureViewportZoom
applyViewportZoom
app.vpZoom
unzoomChartEvent
installChartZoomFix
html{zoom}
html { zoom

Exclude historical changelog text from this gate.

Unit tests

Update tests for the new signatures and native-coordinate behavior.

fixedAnchor

Cover:

  • default gap;
  • custom gap;
  • left alignment;
  • right alignment;
  • minimum inset;
  • zero and fractional coordinates;
  • no scale parameter.

Splitters

Cover:

  • sidebar width follows clientX;
  • drawer width follows viewportWidth - clientX;
  • clamping remains unchanged;
  • percentage axes remain unchanged;
  • startDrag() no longer reads ctx.scale.

Grid columns

Cover:

  • positive and negative native deltas;
  • minimum width;
  • paired-column resize;
  • last-column growth;
  • no scale parameter.

Schema detail

Cover:

  • drag delta maps directly to flex basis;
  • panel-height upper bound uses native height;
  • close during drag removes listeners.

Charts

Remove zoom-event mutation tests.

Retain:

  • chart configuration;
  • Chart.js construction;
  • detached/cross-realm explicit resize;
  • chart destruction and lifecycle.

Detached views

Verify:

  • theme and density still mirror;
  • no zoom custom property is mirrored;
  • panel mounts in tabs and overlay fallback;
  • close/teardown behavior is unchanged.

Browser tests

Use normal application surfaces rather than a synthetic zoom harness.

Run on Chromium, Firefox, and WebKit.

Verify:

  1. File menu opens under the File button and remains inside the viewport.
  2. Save and user popovers align to their triggers.
  3. Variable combobox list aligns with the input.
  4. The recents footer aligns with the combobox and matches its width.
  5. Sidebar resize tracks the cursor.
  6. Editor/results and sidebar vertical splitters retain their behavior.
  7. Cell-detail drawer resize tracks the cursor.
  8. Result-grid column resize tracks the cursor.
  9. Schema-detail height resize tracks the cursor.
  10. Chart hover and tooltip target the correct bar, point, or slice.
  11. Fullscreen graph overlay fits within its padded viewport.
  12. Detached schema, pipeline, and Data views fill their browser tab.
  13. Narrow/mobile popovers remain inside the viewport.

Use tolerances only for normal browser layout rounding. Do not assert a zoom divisor.

Real Safari

A manual real-Safari smoke pass is recommended for release confidence:

  • popovers;
  • comboboxes;
  • splitters;
  • Chart hover;
  • fullscreen overlay;
  • detached view.

It is not a special architectural gate for this issue. The former real-Safari discrepancy was specific to CSS zoom, which this change removes.


Implementation order

1. CSS and viewport measurement

  • remove page zoom declarations;
  • replace overlay and detached sizing;
  • remove zoom-support.js;
  • remove app measurement/publication;
  • remove detached property mirroring.

2. Native anchoring

  • delete zoomScale;
  • simplify fixedAnchor;
  • migrate File menu, application popovers, combobox, and footer.

3. Native drag geometry

  • simplify splitter APIs;
  • simplify grid-column resize;
  • simplify schema-detail resize;
  • remove drawer scale callbacks.

4. Chart cleanup

  • remove event correction;
  • instantiate Chart.js directly;
  • retain cross-realm resize behavior.

5. Tests and documentation

  • delete obsolete zoom harnesses;
  • add behavior-level browser coverage;
  • update comments;
  • update CHANGELOG.md;
  • run repository-wide dead-code search.

Non-goals

Do not include:

  • GraphSurface extraction;
  • graph selection or movement changes;
  • new popover abstractions;
  • new splitter behavior;
  • redesign of detached views;
  • browser zoom detection;
  • application-level UI scaling or density preferences;
  • replacement of CSS zoom with transforms;
  • changes to Chart.js configuration unrelated to event correction.

Browser-native page zoom remains supported by the browser and requires no application compensation.


Acceptance criteria

  • html no longer uses the CSS zoom property.
  • --zoom and --vp-zoom are removed from active CSS and JavaScript.
  • src/core/zoom-support.js is deleted.
  • Runtime viewport probing and publication are deleted.
  • Detached views no longer mirror a viewport-zoom property.
  • zoomScale() is deleted.
  • fixedAnchor() uses native coordinates and has no scale argument.
  • File, Save, user, combobox, and footer anchoring use the simplified helper.
  • Splitter geometry has no scale argument or callback.
  • Grid-column resizing has no scale argument.
  • Schema-detail resizing has no zoom division.
  • Cell-detail drawer resizing has no zoom callback.
  • Chart.js event interception and unzoomChartEvent() are deleted.
  • Cross-realm Chart.js resize behavior remains intact.
  • Overlay panels fill their padded containing block.
  • Detached panels fill their browser tab.
  • Obsolete zoom unit and E2E harnesses are deleted.
  • Active source and tests contain no zoom-compensation identifiers.
  • Popovers, comboboxes, drags, charts, overlays, and detached views pass behavior tests.
  • Chromium, Firefox, and WebKit E2E suites pass.
  • Existing per-file coverage gates remain green.
  • npm test passes.
  • npm run build succeeds.
  • No new runtime dependency is added.

Definition of done

The application uses one coordinate system: native browser CSS pixels.

All fixed-position anchoring, pointer input, layout sizing, drag geometry, Chart.js interaction, overlays, and detached views operate without application-level page-zoom detection or conversion.

Future surfaces, including GraphSurface, have no zoom bridge to inherit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorRestructuring without user-facing behavior change

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions