Skip to content

Commit

Permalink
Merge pull request #313 from marp-team/fix-auto-scaling-repaint-worka…
Browse files Browse the repository at this point in the history
…round

Flush display of `<marp-auto-scaling>` only when resized the scaling wrapper
  • Loading branch information
yhatt authored Aug 12, 2022
2 parents 6b0820f + 5edcef6 commit 72f1776
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- Flush display of `<marp-auto-scaling>` only when resized the scaling wrapper ([#313](https://github.com/marp-team/marp-core/pull/313))

## v3.3.1 - 2022-08-11

### Fixed
Expand Down
35 changes: 17 additions & 18 deletions src/custom-elements/browser/marp-auto-scaling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ export class MarpAutoScaling extends HTMLElement {
this.containerObserver = new ResizeObserver(
generateObserverCallback('containerSize')
)
this.wrapperObserver = new ResizeObserver(
generateObserverCallback('wrapperSize')
)
this.wrapperObserver = new ResizeObserver((...args) => {
generateObserverCallback('wrapperSize')(...args)
this.flushSvgDisplay()
})
}

static get observedAttributes() {
Expand Down Expand Up @@ -70,21 +71,6 @@ export class MarpAutoScaling extends HTMLElement {
: undefined
}

// Workaround for the latest Chromium browser (>= 105?)
// TODO: Remove this workaround when the bug is fixed
if (this.svg) {
const { svg: connectedSvg } = this

// I don't know why but a nested SVG may require to flush the display style for rendering correctly
requestAnimationFrame(() => {
connectedSvg.style.display = 'inline'

requestAnimationFrame(() => {
connectedSvg.style.display = ''
})
})
}

this.container =
this.svg?.querySelector<HTMLSpanElement>(`span[${dataContainer}]`) ??
undefined
Expand All @@ -105,6 +91,19 @@ export class MarpAutoScaling extends HTMLElement {
this.observe()
}

// Workaround for Chromium 105+
private flushSvgDisplay() {
const { svg: connectedSvg } = this

if (connectedSvg) {
connectedSvg.style.display = 'inline'

requestAnimationFrame(() => {
connectedSvg.style.display = ''
})
}
}

private observe() {
this.containerObserver.disconnect()
this.wrapperObserver.disconnect()
Expand Down
9 changes: 3 additions & 6 deletions test/custom-elements/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ describe('The hydration script for custom elements', () => {
const waitNextRendering = () =>
new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))

it("flushes SVG's display style on mounted", async () => {
it("flushes SVG's display style when resized", async () => {
expect.hasAssertions()

browser.applyCustomElements()
Expand All @@ -279,11 +279,8 @@ describe('The hydration script for custom elements', () => {
) as MarpAutoScaling
const svg = autoScaling.shadowRoot.querySelector('svg') as SVGElement

// Initially SVG's display style is not set
expect(svg.style.display).toBe('')

// At the next rendering frame, display style is set as `inline`
await waitNextRendering()
// display style sets as `inline` by an initial callback of ResizeObserver
// (If not yet rendered DOM, running callback would be delayed until the component was painted)
expect(svg.style.display).toBe('inline')

// After that, display style is reverted to empty string
Expand Down

0 comments on commit 72f1776

Please sign in to comment.