mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
Prevent block decoration margins from collapsing during measurement
We now render a 1px high sentinel element between off-screen block decorations before measuring them to prevent margins from collapsing.
This commit is contained in:
@@ -1982,7 +1982,6 @@ describe('TextEditorComponent', () => {
|
||||
})
|
||||
|
||||
describe('block decorations', () => {
|
||||
it('renders visible block decorations between the appropriate lines, refreshing and measuring them as needed', async () => {
|
||||
const editor = buildEditor({autoHeight: false})
|
||||
const {item: item1, decoration: decoration1} = createBlockDecorationAtScreenRow(editor, 0, {height: 11, position: 'before'})
|
||||
const {item: item2, decoration: decoration2} = createBlockDecorationAtScreenRow(editor, 2, {height: 22, margin: 10, position: 'before'})
|
||||
@@ -2010,8 +2009,8 @@ describe('TextEditorComponent', () => {
|
||||
// add block decorations
|
||||
const {item: item3, decoration: decoration3} = createBlockDecorationAtScreenRow(editor, 4, {height: 33, position: 'before'})
|
||||
const {item: item4, decoration: decoration4} = createBlockDecorationAtScreenRow(editor, 7, {height: 44, position: 'before'})
|
||||
const {item: item5, decoration: decoration5} = createBlockDecorationAtScreenRow(editor, 7, {height: 55, position: 'after'})
|
||||
const {item: item6, decoration: decoration6} = createBlockDecorationAtScreenRow(editor, 12, {height: 66, position: 'after'})
|
||||
const {item: item5, decoration: decoration5} = createBlockDecorationAtScreenRow(editor, 7, {height: 50, marginBottom: 5, position: 'after'})
|
||||
const {item: item6, decoration: decoration6} = createBlockDecorationAtScreenRow(editor, 12, {height: 60, marginTop: 6, position: 'after'})
|
||||
await component.getNextUpdatePromise()
|
||||
expect(component.getRenderedStartRow()).toBe(0)
|
||||
expect(component.getRenderedEndRow()).toBe(9)
|
||||
@@ -2343,11 +2342,13 @@ describe('TextEditorComponent', () => {
|
||||
expect(editor.getCursorScreenPosition()).toEqual([0, 0])
|
||||
})
|
||||
|
||||
function createBlockDecorationAtScreenRow(editor, screenRow, {height, margin, position}) {
|
||||
function createBlockDecorationAtScreenRow(editor, screenRow, {height, margin, marginTop, marginBottom, position}) {
|
||||
const marker = editor.markScreenPosition([screenRow, 0], {invalidate: 'never'})
|
||||
const item = document.createElement('div')
|
||||
item.style.height = height + 'px'
|
||||
if (margin != null) item.style.margin = margin + 'px'
|
||||
if (marginTop != null) item.style.marginTop = marginTop + 'px'
|
||||
if (marginBottom != null) item.style.marginBottom = marginBottom + 'px'
|
||||
item.style.width = 30 + 'px'
|
||||
const decoration = editor.decorateMarker(marker, {type: 'block', item, position})
|
||||
return {item, decoration}
|
||||
|
||||
@@ -120,6 +120,8 @@ class TextEditorComponent {
|
||||
this.horizontalPixelPositionsByScreenLineId = new Map() // Values are maps from column to horiontal pixel positions
|
||||
this.blockDecorationsToMeasure = new Set()
|
||||
this.blockDecorationsByElement = new WeakMap()
|
||||
this.blockDecorationSentinel = document.createElement('div')
|
||||
this.blockDecorationSentinel.style.height = '1px'
|
||||
this.heightsByBlockDecoration = new WeakMap()
|
||||
this.blockDecorationResizeObserver = new ResizeObserver(this.didResizeBlockDecorations.bind(this))
|
||||
this.lineNodesByScreenLineId = new Map()
|
||||
@@ -309,21 +311,22 @@ class TextEditorComponent {
|
||||
const parentElement = decorationElement.parentElement
|
||||
|
||||
if (!decorationElement.previousSibling) {
|
||||
const sentinelElement = document.createElement('div')
|
||||
const sentinelElement = this.blockDecorationSentinel.cloneNode()
|
||||
parentElement.insertBefore(sentinelElement, decorationElement)
|
||||
sentinelElements.add(sentinelElement)
|
||||
}
|
||||
|
||||
if (!decorationElement.nextSibling) {
|
||||
const sentinelElement = document.createElement('div')
|
||||
const sentinelElement = this.blockDecorationSentinel.cloneNode()
|
||||
parentElement.appendChild(sentinelElement)
|
||||
sentinelElements.add(sentinelElement)
|
||||
}
|
||||
|
||||
this.didMeasureVisibleBlockDecoration = true
|
||||
} else {
|
||||
blockDecorationMeasurementArea.appendChild(this.blockDecorationSentinel.cloneNode())
|
||||
blockDecorationMeasurementArea.appendChild(decorationElement)
|
||||
blockDecorationMeasurementArea.appendChild(document.createElement('div'))
|
||||
blockDecorationMeasurementArea.appendChild(this.blockDecorationSentinel.cloneNode())
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user