← All issues

Table Rendering: RenderTableRow Promoted to RenderBlock

27d1a32

Source/WebCore/rendering/RenderLayer.cpp

- if (auto* boxRenderer = dynamicDowncast<RenderBox>(ancestor)) {
- // Row와 셀은 동일한 좌표 공간(section 기준)을 공유합니다.
- // xpos/ypos 계산 시 제외합니다.
- if (!is<RenderTableRow>(boxRenderer))
- localPoint += boxRenderer->topLeftLocationOffset();
- }
+ if (auto* boxRenderer = dynamicDowncast<RenderBox>(ancestor))
+ localPoint += boxRenderer->topLeftLocationOffset();
ancestor = ancestor->parent();
- if (auto* tableRow = dynamicDowncast<RenderTableRow>(ancestor)) {
- // row 좌표 공간으로 진입합니다.
- localPoint -= tableRow->topLeftLocationOffset();
- }

Source/WebCore/rendering/RenderTableSection.cpp

- // Cell Y = m_rowPos[rowIndex] (section 기준)
+ // Cell Y = 0 (row 기준; section offset은 row가 보유)

이 commit은 WebKit table rendering의 좌표계를 근본적으로 재구성합니다. RenderTableRowRenderBox에서 RenderBlock으로 승격되면서, table row가 절대 위치 지정 자식 요소의 정식 containing block이 됩니다.

기존에는 containingBlock() 탐색이 RenderBlock이 아닌 ancestor를 건너뛰는 구조였습니다. RenderBox를 상속하던 <tr>은 containing block으로 인식되지 않았고, 절대 위치 지정 자식은 row를 지나쳐 상위 요소로 빠져나갔습니다. 이를 우회하기 위해 style 시스템은 row에 position: static을 강제 적용했습니다. 셀의 위치는 section(RenderTableSection) 기준으로 누적되었고, 좌표 변환이 필요한 subsystem마다 row를 건너뛰거나 offset을 보정하는 독자적인 로직이 생겨났습니다. 이 commit은 그런 workaround 약 10개를 일괄 제거했습니다.

Before:                                          After:

Nearest positioned ancestor                      RenderTableRow (RenderBlock)
  (e.g. viewport or positioned div)                └─ RenderTableCell
  └─ abspos child  ◄── escapes past                    └─ abspos descendant  ──► sized/positioned
        RenderTableSection                                                        relative to row
          (coordinate origin for cells)
          └─ RenderTableRow (RenderBox, not a containing block)
               └─ RenderTableCell

Coordinate origin for cells:
  Before: section-relative (m_rowPos[rowIndex] baked into cell position)
  After:  row-relative     (cell Y = 0; row carries the section offset)

이 변경 하나로, 모든 table의 모든 cell 좌표 기준이 이동하고, positioned row에 대한 RenderLayer 생성이 도입되며, 기존에 static이었던 element type에 out-of-flow layout이 연결되고, sticky constraint 로직까지 함께 조정됩니다.

이 변경은 layer 위치 결정, hit testing, paint, sticky layout, fragmented flow, out-of-flow layout에 모두 영향을 미칩니다. position 속성이 있는 <tr> 요소는 이제 RenderLayer를 생성합니다. layout 이후 row에 position: relative를 추가하거나 제거하는 동적 style 변경이 발생하면, 새로운 context에서 layer creation/destruction 경로가 실행됩니다. 한편 clearNeedsLayout() 호출이 RenderTableRow::layout()에서 RenderTableSection::layoutRows()로 이동되었습니다. 탐색 도중 relayout이 발생하여 layoutRows가 조기에 종료될 경우, row의 최종 크기가 확정되지 않은 상태에서 needsLayout()이 지워질 가능성이 있습니다.

🔒

A sweeping coordinate-system change across the table rendering pipeline — several new code paths and interaction edges are worth security investigation.

더 확인하려면 구독해 주세요