Skip to content

Fix dragged row offset from cursor in Chrome for contest/testcase reordering#671

Open
leduythuccs wants to merge 1 commit into
masterfrom
thuc/fix-drag-and-drop
Open

Fix dragged row offset from cursor in Chrome for contest/testcase reordering#671
leduythuccs wants to merge 1 commit into
masterfrom
thuc/fix-drag-and-drop

Conversation

@leduythuccs

Copy link
Copy Markdown
Contributor

Dragging a row to reorder problems (contest edit) or test cases
(problem data edit) showed the dragged row offset from the cursor in
Chrome, growing worse the further down the page the table sat. Firefox
and Safari were unaffected.

Root cause: jQuery UI Sortable's default helper positions the dragged

with `position: absolute` and computes its top/left relative to its offsetParent. Two things throw that off in this codebase:
  • body/html have position: relative (needed for the sticky footer),
    which Chrome and Firefox resolve differently as the offsetParent for
    table-row elements.
  • .table sets backdrop-filter (table.scss), which per spec makes
    the table itself a CSS containing block for absolute/fixed
    descendants, trapping the helper's positioning inside the table's
    own box instead of the viewport.

Fix: in the sortable start handler, suspend backdrop-filter on the
table for the duration of the drag, then switch the helper to
position: fixed and drive it with raw viewport coordinates
(event.clientX/clientY) on every sort tick, instead of relying on
jQuery UI's offsetParent-relative math. The rect is read before
switching position (and fixed/top/left are set atomically) so the
helper doesn't briefly jump when jQuery UI's old absolute-relative
top/left gets reinterpreted under fixed semantics.

…rdering

Dragging a row to reorder problems (contest edit) or test cases
(problem data edit) showed the dragged row offset from the cursor in
Chrome, growing worse the further down the page the table sat. Firefox
and Safari were unaffected.

Root cause: jQuery UI Sortable's default helper positions the dragged
<tr> with `position: absolute` and computes its top/left relative to
its offsetParent. Two things throw that off in this codebase:

- body/html have `position: relative` (needed for the sticky footer),
  which Chrome and Firefox resolve differently as the offsetParent for
  table-row elements.
- `.table` sets `backdrop-filter` (table.scss), which per spec makes
  the table itself a CSS containing block for absolute/fixed
  descendants, trapping the helper's positioning inside the table's
  own box instead of the viewport.

Fix: in the sortable `start` handler, suspend `backdrop-filter` on the
table for the duration of the drag, then switch the helper to
`position: fixed` and drive it with raw viewport coordinates
(event.clientX/clientY) on every `sort` tick, instead of relying on
jQuery UI's offsetParent-relative math. The rect is read before
switching position (and fixed/top/left are set atomically) so the
helper doesn't briefly jump when jQuery UI's old absolute-relative
top/left gets reinterpreted under fixed semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant