Skip to content

Commit

Permalink
Merge pull request #21 from marp-team/follow-parent-zoom-factor
Browse files Browse the repository at this point in the history
Follow zoom factor in parent window from <iframe>
  • Loading branch information
yhatt authored Jul 9, 2020
2 parents ea3ec1e + cf60e37 commit ff37544
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 31 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

- Follow zoom factor of the parent window in `<iframe>` ([#21](https://github.com/marp-team/marpit-svg-polyfill/pull/21))

### Changed

- Upgrade development Node LTS ans dependent packages to the latest version ([#22](https://github.com/marp-team/marpit-svg-polyfill/pull/22))
Expand Down
25 changes: 23 additions & 2 deletions src/polyfill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ export function observe() {
export const polyfills = () =>
navigator.vendor === 'Apple Computer, Inc.' ? [webkit] : []

let previousZoomFactor: number | undefined = undefined

export function webkit(zoom?: number) {
let changedZoomFactor: false | number = false

Array.from(
document.querySelectorAll<SVGSVGElement>('svg[data-marpit-svg]'),
(svg) => {
Expand All @@ -31,8 +35,18 @@ export function webkit(zoom?: number) {

// NOTE: Safari reflects a zoom level to SVG's currentScale property, but
// the other browsers will always return 1. You have to specify the zoom
// factor manually if it is used in outdated Blink engine. (e.g. Electron)
const zoomFactor = zoom || svg.currentScale || 1
// factor manually if used in outdated Blink engine. (e.g. Electron)
const zoomFactor =
zoom ||
(window !== window.parent &&
window.parent['marpitSVGPolyfillZoomFactor']) ||
svg.currentScale ||
1

if (previousZoomFactor !== zoomFactor) {
previousZoomFactor = zoomFactor
changedZoomFactor = zoomFactor
}

const width = viewBox.baseVal.width / zoomFactor
const height = viewBox.baseVal.height / zoomFactor
Expand All @@ -48,4 +62,11 @@ export function webkit(zoom?: number) {
}
}
)

if (changedZoomFactor !== false) {
Object.defineProperty(window, 'marpitSVGPolyfillZoomFactor', {
configurable: true,
value: changedZoomFactor,
})
}
}
66 changes: 37 additions & 29 deletions test/polyfill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,9 @@ describe('Marpit SVG polyfill', () => {
document.body.innerHTML = marpit.render('').html

Array.from(document.querySelectorAll('svg'), (svg: any) => {
jest.spyOn(svg, 'clientWidth', 'get').mockImplementation(() => 640)
jest.spyOn(svg, 'clientHeight', 'get').mockImplementation(() => 360)
svg.viewBox = { baseVal: { width: 1280, height: 720 } }

const foreignObjects = Array.from(
svg.querySelectorAll('foreignObject'),
(foreignObject: any) => {
foreignObject.x = { baseVal: { value: 0 } }
foreignObject.y = { baseVal: { value: 0 } }

// mock for unsupported `:scope` selector
jest
.spyOn(foreignObject, 'querySelectorAll')
.mockImplementation(() => document.querySelectorAll('section'))

return foreignObject
}
)

// mock for unsupported `:scope` selector
jest
.spyOn(svg, 'querySelectorAll')
.mockImplementation(() => foreignObjects)
})
})

Expand All @@ -72,23 +54,49 @@ describe('Marpit SVG polyfill', () => {
})

it('applies calculated transform style to section elements for scaling', () => {
const sections = document.getElementsByTagName('section')
expect.hasAssertions()

Array.from(sections, (section) => {
const { transform, transformOrigin } = section.style
const sections = document.getElementsByTagName('section')

expect(transformOrigin).toBeFalsy()
expect(transform).not.toContain('scale')
Array.from(sections, ({ style }) => {
expect(style.transformOrigin).toBeFalsy()
expect(style.transform).not.toContain('scale')
})

webkit()

Array.from(sections, (section) => {
const { transform, transformOrigin } = section.style
Array.from(sections, ({ style }) => {
expect(style.transformOrigin).toBe('0 0')
expect(style.transform).toContain('scale(0.5)')
})
})

it("takes account of SVG's currentScale property", () => {
expect.hasAssertions()

expect(transformOrigin).toBe('0 0')
expect(transform).toContain('scale')
Array.from(document.querySelectorAll('svg'), (svg) => {
svg.currentScale = 1.25
})

webkit()

Array.from(document.getElementsByTagName('section'), ({ style }) =>
expect(style.transform).toContain('scale(0.625)')
)
})

it('prefers the zoom factor defined in parent.marpitSVGPolyfillZoomFactor', () => {
expect.hasAssertions()

jest.spyOn(window, 'parent', 'get').mockImplementation((): any => ({
marpitSVGPolyfillZoomFactor: 2,
}))

webkit()

Array.from(document.getElementsByTagName('section'), ({ style }) =>
expect(style.transform).toContain('scale(1)')
)
})
})
})

0 comments on commit ff37544

Please sign in to comment.